Skip to content

Commit 45d6caf

Browse files
phernandezclaude
andcommitted
fix: remove MaxLen constraint from observation content
The API Pydantic schema had a MaxLen(1000) constraint on observation content while the database uses SQLAlchemy's Text type (unlimited). This mismatch caused validation errors when observations exceeded 1000 characters (e.g., JSON schemas with 1458+ chars). Removed the MaxLen constraint to match the DB schema. Retained: - BeforeValidator(str.strip) for whitespace cleaning - MinLen(1) to ensure non-empty content Added comprehensive tests to verify: - Long content (10K+ chars) is accepted - Very long content (50K+ chars) is accepted - Empty/whitespace-only content is still rejected - Whitespace stripping still works Fixes #385 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <[email protected]> Signed-off-by: phernandez <[email protected]>
1 parent 1652f86 commit 45d6caf

File tree

2 files changed

+43
-1
lines changed

2 files changed

+43
-1
lines changed

src/basic_memory/schemas/base.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -183,7 +183,7 @@ def validate_timeframe(timeframe: str) -> str:
183183
str,
184184
BeforeValidator(str.strip), # Clean whitespace
185185
MinLen(1), # Ensure non-empty after stripping
186-
MaxLen(1000), # Keep reasonable length
186+
# No MaxLen - matches DB Text column which has no length restriction
187187
]
188188

189189

tests/schemas/test_schemas.py

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -466,3 +466,45 @@ class TestModel(BaseModel):
466466
# They should be approximately the same time (within an hour due to parsing differences)
467467
time_diff = abs((today_parsed - oneday_parsed).total_seconds())
468468
assert time_diff < 3600, f"'today' and '1d' should be similar times, diff: {time_diff}s"
469+
470+
471+
class TestObservationContentLength:
472+
"""Test observation content length validation matches DB schema."""
473+
474+
def test_observation_accepts_long_content(self):
475+
"""Observation content should accept unlimited length to match DB Text column."""
476+
from basic_memory.schemas.base import Observation
477+
478+
# Very long content that would have failed with old MaxLen(1000) limit
479+
long_content = "x" * 10000
480+
481+
obs = Observation(category="test", content=long_content)
482+
assert len(obs.content) == 10000
483+
484+
def test_observation_accepts_very_long_content(self):
485+
"""Observation content should accept very long content like JSON schemas."""
486+
from basic_memory.schemas.base import Observation
487+
488+
# Simulate the JSON schema content from issue #385 (1458+ chars)
489+
json_schema_content = '{"$schema": "http://json-schema.org/draft-07/schema#"' + "x" * 50000
490+
491+
obs = Observation(category="schema", content=json_schema_content)
492+
assert len(obs.content) > 50000
493+
494+
def test_observation_still_requires_non_empty_content(self):
495+
"""Observation content must still be non-empty after stripping."""
496+
from basic_memory.schemas.base import Observation
497+
from pydantic import ValidationError
498+
499+
with pytest.raises(ValidationError):
500+
Observation(category="test", content="")
501+
502+
with pytest.raises(ValidationError):
503+
Observation(category="test", content=" ") # whitespace only
504+
505+
def test_observation_strips_whitespace(self):
506+
"""Observation content should have whitespace stripped."""
507+
from basic_memory.schemas.base import Observation
508+
509+
obs = Observation(category="test", content=" some content ")
510+
assert obs.content == "some content"

0 commit comments

Comments
 (0)