thedotmack/claude-mem · warning

Failed to parse files_read JSON

Error message

Failed to parse files_read JSON

What it means

The second parse attempt in extractRelevantFile: obs.files_read is parsed as a JSON array of paths to find a direct child of the folder. Invalid JSON triggers this warning and the function returns 'General' as the section label. Non-fatal; only the generated CLAUDE.md section naming degrades.

Solutions

  1. Rewrite files_read as a valid JSON array of path strings
  2. Null the field when empty rather than storing '' or garbage
  3. Regenerate the observation via the normal capture pipeline
  4. Add a migration to normalize/blank legacy malformed values

Example fix

// before
obs.files_read = '["src/a.ts"';
// after
obs.files_read = '["src/a.ts"]';
Defensive patterns

Strategy: validation

Validate before calling

if (obs.files_read) {
  try { const read = JSON.parse(obs.files_read); if (Array.isArray(read)) { /* use */ } } catch { /* use 'General' */ }
}

Type guard

function isJsonArrayString(v: unknown): v is string { return typeof v === 'string' && v.trimStart().startsWith('['); }

Try / catch

try { read = JSON.parse(obs.files_read); } catch { read = []; } // default keeps flow to 'General'

Prevention

When it happens

Trigger: obs.files_read holds malformed JSON — a plain path string, truncated array like '["src/a.ts"', single-quoted entries, or non-string JSON (e.g. an object) that passes parse but not Array.isArray, leaving paths undefined downstream (though the warn itself fires only on throw).

Common situations: Historic rows predating the array format; corrupted DB rows after a crash; observations written by external scripts; manual DB edits.

Understand the failure class

Background: JSON parse error: "Unexpected token" / "not valid JSON" / "failed to parse" — what JSON parsers are really complaining about — this error's family across 45 libraries.

Related errors


AI-assisted analysis of thedotmack/claude-mem@d8bc9755e7 (2026-09-17). Data as JSON: /api/errors/903a6e15a48e6788. Report an issue: GitHub.

Appendix: source

Thrown at src/cli/claude-md-commands.ts:182

        }
      }
    } catch (error) {
      logger.warn('CLAUDE_MD', 'Failed to parse files_modified JSON', { error: error instanceof Error ? error.message : String(error) });
    }
  }

  if (obs.files_read) {
    try {
      const read = JSON.parse(obs.files_read);
      if (Array.isArray(read)) {
        for (const file of read) {
          if (isDirectChild(file, relativeFolder)) {
            return path.basename(file);
          }
        }
      }
    } catch (error) {
      logger.warn('CLAUDE_MD', 'Failed to parse files_read JSON', { error: error instanceof Error ? error.message : String(error) });
    }
  }

  return 'General';
}

function formatObservationsForClaudeMd(observations: ObservationRow[], folderPath: string): string {
  const lines: string[] = [];
  lines.push('# Recent Activity');
  lines.push('');
  lines.push('<!-- This section is auto-generated by claude-mem. Edit content outside the tags. -->');
  lines.push('');

  if (observations.length === 0) {
    lines.push('*No recent activity*');
    return lines.join('\n');
  }

View on GitHub (pinned to d8bc9755e7)