Skip to content

[Bug] cleo docs add fails with E_INTERNAL: Failed to run the query '\n' — attachment-store-v2 regression blocks entire docs E2E flow #98

@kryptobaseddev

Description

@kryptobaseddev

Bug Report

Summary

cleo docs add <owner-id> <file> fails with E_INTERNAL: Failed to run the query '\n' (literally a newline-only SQL string). This blocks the entire attachment-based end-to-end flow for cleo docs, including list, fetch, remove, and any command that depends on attachment-store-v2 (which in turn gates publish, versions, and the full "document store for a project" vision).

The llmtxt npm dependency (llmtxt@2026.4.13) and its WASM binding are working correctly — verified via the published package's own test suite (700/700 passing) and an independent 25-doc end-to-end scale test (T848) that exercises every SDK primitive directly. The failure is isolated to cleocode's attachment-store-v2 layer.

There is an existing acknowledgement of related flakes at .cleo/agent-outputs/T-ATTACHMENT-V2-LLMTXT-BUGS/REPORT.md (CI run 24669599191, 5 tests returning 'legacy' instead of 'llmtxt'). This bug is likely the same root cause surfacing at runtime rather than just in tests.

Environment

  • cleo version: 2026.4.101 (rebuilt from source at HEAD bc082e26c feat(docs): full docs SSoT surface — 6 new verbs + llmtxt v2026.4.13)
  • node: v24.13.1
  • llmtxt npm: 2026.4.13 (published 2026-04-21, OIDC npm provenance attested, 700/700 tests green, cargo test cargo test --all-features all green)
  • llmtxt-core crate: 2026.4.13 (crates.io)
  • ferrous-forge: 1.9.8 (published, ✅ All validation checks passed! on llmtxt crate)
  • Shell alias for ferrous-forge has been unset in favour of /home/keatonhoskins/.cargo/bin/ferrous-forge
  • Host project being tested: /mnt/projects/llmtxt (has .cleo/tasks.db, brain.db, conduit.db — no signaldock.db)

Reproduction

From a clean llmtxt checkout with CLEO already initialised:

cd /mnt/projects/llmtxt
mkdir -p .cleo/test-attachments
printf '# Auth Design\n\nJWT with ES256 signing.\n' > .cleo/test-attachments/auth.md

# Use any existing task ID — same failure across T814 (done), T781 (pending), T780 (epic)
cleo docs add T781 .cleo/test-attachments/auth.md 2>&1 | tail -3

Observed output

{
  "level": "WARN",
  "time": 1776751612631,
  "subsystem": "sqlite",
  "msg": "Backfilling missing name on journal entry id=null — Drizzle v1 beta requires name for applied-migration detection."
}
{
  "level": "WARN",
  "time": 1776751612654,
  "subsystem": "sqlite",
  "msg": "Backfilling missing name on journal entry id=null — Drizzle v1 beta requires name for applied-migration detection."
}
{
  "success": false,
  "error": {
    "code": 1,
    "message": "Failed to run the query '\n'",
    "codeName": "E_INTERNAL"
  },
  "meta": {
    "operation": "docs.add",
    "requestId": "526b57b9-485f-4e50-beb8-30866b73301e",
    "duration_ms": 49,
    "timestamp": "2026-04-21T06:06:52.657Z"
  }
}

Note the SQL query literal is '\n' — a bare newline string. No columns, no table. That means somewhere a query template rendered with every interpolation collapsed.

Expected output

{
  "success": true,
  "data": {
    "attachmentId": "att_...",
    "sha256": "<hash>",
    "size": 42,
    "backend": "llmtxt"
  }
}

Downstream impact — what else this blocks

cleo docs list --task <id> returns ownerId.startsWith is not a function (which is ALSO a v2-store-path failure masquerading as a different error — the handler passes undefined through because the store couldn't index).

cleo docs fetch, remove, publish, versions, graph --owner, search --owner all resolve to 0 hits / empty / secondary errors because no attachments can be created.

Only the pure-SDK-delegating subcommands with no attachment dependency work end-to-end: search (returns hits=0 when no attachments), rank (returns empty), graph (returns nodes=0/edges=0), versions (returns 0), generate (works against the fallback generator), export (works standalone), sync, gap-check.

Root-cause hypotheses (ranked)

  1. Migration state / ensureLlmtxt silent swallow. Per existing report .cleo/agent-outputs/T-ATTACHMENT-V2-LLMTXT-BUGS/REPORT.md, ensureLlmtxt() catches store.open() failures silently. If the v2 store opens partially and returns a misconfigured drizzle instance, the subsequent drizzle-orm query template can render with no params and emit '\n'. The two preceding Backfilling missing name on journal entry id=null WARNs from drizzle v1 beta strongly suggest a migration state-machine issue: the store opens, tries to backfill, but the post-backfill query path lands on an incomplete schema. The llmtxt/blob peer dep resolves, the feature-gate passes, but the attachment table isn't present or usable in the host project's .cleo/ — there is no signaldock.db in the llmtxt checkout's .cleo/ (only tasks.db, brain.db, conduit.db). v2 likely expects a separate attachments DB file that was never initialised.

  2. Drizzle v1 beta template regression. The introduction of llmtxt@^2026.4.13 (which peers on drizzle-orm >=1.0.0-beta.21) may have shifted the resolved drizzle version in cleocode's workspace, and a query template that used to render INSERT INTO attachments ... now produces '\n' because of a tagged-template handling change.

  3. Missing cleo init step for attachment DB. cleo init on this project returns Project already initialized. DANGER ZONE: use --force to wipe and re-init. — no opportunity to create the attachment store without a destructive reset. If v2 expects a schema that only cleo init produces, there's no idempotent migration path on an existing project.

Why we believe it is NOT an llmtxt bug

  • llmtxt@2026.4.13 npm tarball is clean: 700/700 tests green, smoke harness T833 (32/32) and scale test T848 (25 real docs) both pass with the exact published artefact.
  • packages/core/src/docs/docs-ops.ts::searchDocs, mergeDocs, buildDocsGraph, rankDocs all invoke llmtxt/similarity, llmtxt/sdk, llmtxt/graph correctly and return sane empty-state results from cleo CLI — the SDK surface is intact.
  • The error message "Failed to run the query '\n'" is raised by cleocode's own DB layer (drizzle-orm via better-sqlite3); no llmtxt code runs in the docs.add path until after the local attachment row is written.
  • The llmtxt SDK has zero code paths that would interpolate an empty string into a SQL template — all SDK primitives are pure functions over Rust/WASM with no DB access.

References

  • cleocode HEAD: bc082e26c feat(docs): full docs SSoT surface — 6 new verbs + llmtxt v2026.4.13
  • Related existing report: .cleo/agent-outputs/T-ATTACHMENT-V2-LLMTXT-BUGS/REPORT.md
  • llmtxt release: https://github.com/kryptobaseddev/llmtxt/releases/tag/core-v2026.4.13
  • llmtxt vision scale test (bypasses cleocode attachment layer, proves SDK works): /mnt/projects/llmtxt/.cleo/agent-outputs/T780-vision-scale-report.md
  • Epic context: T780 Wave-1 + Wave-2 shipped 2026-04-21

Suggested remediation order

  1. Re-read T-ATTACHMENT-V2-LLMTXT-BUGS/REPORT.md — the flaky 'legacy' vs 'llmtxt' return is likely the same root cause as the runtime empty-SQL error. Fixing the test should fix runtime.
  2. Add a cleo admin init-attachments (or idempotent cleo init --attachments-only) that materialises the attachment store without requiring --force.
  3. Surface a proper error when ensureLlmtxt() swallows a store.open() failure — log and return a named error code rather than silently falling through to the legacy path which then emits a cryptic empty-query error.
  4. Add an E2E smoke test that asserts cleo docs add && cleo docs list returns exactly one attachment on a fresh project — this would have caught the regression before the feat(docs) commit landed.

Severity: Blocker
Area: docs

Are you using an AI agent?

Yes - AI agent filed this issue


Environment

Component Version
CLEO 2026.2.1
Node.js v24.13.1
OS linux 6.19.11-200.fc43.x86_64 x64 (x64)
Shell /bin/bash
gh CLI gh version 2.87.3 (2026-02-23)
Install /home/keatonhoskins/.npm-global/bin/cleo

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions