fix: observation parsing and permalink limits (#446) · basicmachines-co/basic-memory@73d940e · GitHub
Skip to content

Commit 73d940e

Browse files
phernandezclaude
andcommitted
fix: observation parsing and permalink limits (#446)
1. Hashtag detection now checks for standalone words starting with # instead of just checking if # appears anywhere in content. This prevents HTML color codes like #4285F4 from being interpreted as hashtags. 2. Observation permalinks now truncate content to 200 chars to stay under PostgreSQL's btree index limit of 2704 bytes. Added tests for both fixes. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> Signed-off-by: phernandez <paul@basicmachines.co>
1 parent c3678a1 commit 73d940e

4 files changed

Lines changed: 139 additions & 2 deletions

File tree

src/basic_memory/markdown/plugins.py

Lines changed: 3 additions & 1 deletion

src/basic_memory/models/knowledge.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -162,9 +162,14 @@ def permalink(self) -> str:
162162
163163
We can construct these because observations are always defined in
164164
and owned by a single entity.
165+
166+
Content is truncated to 200 chars to stay under PostgreSQL's
167+
btree index limit of 2704 bytes.
165168
"""
169+
# Truncate content to avoid exceeding PostgreSQL's btree index limit
170+
content_for_permalink = self.content[:200] if len(self.content) > 200 else self.content
166171
return generate_permalink(
167-
f"{self.entity.permalink}/observations/{self.category}/{self.content}"
172+
f"{self.entity.permalink}/observations/{self.category}/{content_for_permalink}"
168173
)
169174

170175
def __repr__(self) -> str: # pragma: no cover

tests/markdown/test_markdown_plugins.py

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,44 @@ def test_observation_excludes_markdown_and_wiki_links():
121121
assert not is_observation(token), "No space after category should not be valid observation"
122122

123123

124+
def test_observation_excludes_html_color_codes():
125+
"""Test that HTML color codes are NOT interpreted as hashtags.
126+
127+
This test validates the fix for issue #446 where:
128+
- HTML color codes like #4285F4 in attributes were incorrectly
129+
causing lines to be parsed as observations.
130+
"""
131+
# HTML color code in font tag should NOT be an observation
132+
token = Token("inline", '**<font color="#4285F4">Jane:</font>** Welcome to the show', 0)
133+
assert not is_observation(token), "HTML color codes should not trigger hashtag detection"
134+
135+
# Color code in style attribute
136+
token = Token("inline", '<span style="color:#FF5733">Styled text</span>', 0)
137+
assert not is_observation(token), "Color codes in style should not be observations"
138+
139+
# Multiple color codes
140+
token = Token(
141+
"inline", '<font color="#4285F4">Blue</font> and <font color="#EA4335">Red</font>', 0
142+
)
143+
assert not is_observation(token), "Multiple color codes should not be observations"
144+
145+
# Hex color without quotes (edge case)
146+
token = Token("inline", "background-color:#FFFFFF is white", 0)
147+
assert not is_observation(token), "Inline hex colors should not be observations"
148+
149+
# But standalone hashtags SHOULD still work
150+
token = Token("inline", "This has a #realtag in it", 0)
151+
assert is_observation(token), "Standalone hashtags should still work"
152+
153+
# Multiple real hashtags
154+
token = Token("inline", "Tags: #design #feature #important", 0)
155+
assert is_observation(token), "Multiple standalone hashtags should work"
156+
157+
# Mix of color code and real tag - should be observation because of real tag
158+
token = Token("inline", '<font color="#4285F4">Text</font> #actualtag', 0)
159+
assert is_observation(token), "Real hashtag with color code should still be observation"
160+
161+
124162
def test_relation_plugin():
125163
"""Test relation plugin."""
126164
md = MarkdownIt().use(relation_plugin)

tests/repository/test_observation_repository.py

Lines changed: 92 additions & 0 deletions

0 commit comments

Comments
 (0)