{"record":{"id":"aabe101226caf678","repo":"can1357/oh-my-pi","slug":"sqlite-schema-for-table-table-is-unavailable","errorCode":null,"errorMessage":"SQLite schema for table '${table}' is unavailable","messagePattern":"SQLite schema for table '(.+?)' is unavailable","errorType":"exception","errorClass":"ToolError","httpStatus":null,"severity":"error","filePath":"packages/coding-agent/src/tools/sqlite-reader.ts","lineNumber":688,"sourceCode":"\t\t)\n\t\t.all();\n\tconst estimates = loadRowEstimates(db);\n\n\treturn names.map(({ name }) => {\n\t\tconst estimate = estimates.get(name);\n\t\t// Trust the planner only when it says the table is too large to count\n\t\t// cheaply; otherwise count exactly (bounded), which also corrects a\n\t\t// stale-low estimate without ever scanning more than `cap` rows.\n\t\tconst count: TableRowCount =\n\t\t\testimate !== undefined && estimate > cap ? { kind: \"estimate\", rows: estimate } : probeRowCount(db, name, cap);\n\t\treturn { name, count };\n\t});\n}\n\nexport function getTableSchema(db: Database, table: string): string {\n\tconst row = getTableMasterRow(db, table);\n\tif (!row.sql) {\n\t\tthrow new ToolError(`SQLite schema for table '${table}' is unavailable`);\n\t}\n\treturn row.sql;\n}\n\nexport function getTablePrimaryKey(db: Database, table: string): { column: string; type: string } | null {\n\tconst primaryKeyColumns = getPrimaryKeyColumns(db, table);\n\tif (primaryKeyColumns.length !== 1) {\n\t\treturn null;\n\t}\n\n\tconst column = primaryKeyColumns[0]!;\n\treturn { column: column.name, type: column.type };\n}\n\nexport function resolveTableRowLookup(db: Database, table: string): SqliteRowLookup {\n\tconst primaryKeyColumns = getPrimaryKeyColumns(db, table);\n\tif (primaryKeyColumns.length === 1) {\n\t\tconst column = primaryKeyColumns[0]!;","sourceCodeStart":670,"sourceCodeEnd":706,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/coding-agent/src/tools/sqlite-reader.ts#L670-L706","documentation":"getTableSchema reads the CREATE statement from sqlite_master via getTableMasterRow and throws when the stored `sql` column is null/empty. SQLite stores NULL in sqlite_master.sql for certain internal or implicitly created objects (e.g. auto-indexes), so no schema text exists to return.","triggerScenarios":"Calling getTableSchema on a table whose sqlite_master row has sql IS NULL — typically an internal object like an implicit index (`sqlite_autoindex_*`) or a shadow/legacy object that getTableMasterRow matched but which was never created by explicit SQL.","commonSituations":"Enumerating all schema objects and hitting auto-indexes created by UNIQUE constraints; requesting a schema for a virtual-table shadow table; a corrupted or partially migrated database.","solutions":["Verify the name refers to a real table, not an internal index — query `SELECT name, type, sql FROM sqlite_master WHERE name = ?` yourself","Inspect the table's columns via PRAGMA table_info instead of the CREATE statement","If it's a UNIQUE-constraint auto-index, the constraint is visible in the schema of the parent table"],"exampleFix":"// before\nconst schema = getTableSchema(db, \"sqlite_autoindex_users_1\");\n// after\nconst row = db.query(\"SELECT type, sql FROM sqlite_master WHERE name = ?\").get(\"sqlite_autoindex_users_1\");\nif (!row?.sql) console.log(\"internal object; check parent table schema instead\");","handlingStrategy":"try-catch","validationCode":"const row = db.query(\"SELECT type, sql FROM sqlite_master WHERE name = ? AND type = 'table'\").get(tableName);\nif (!row || typeof row.sql !== \"string\" || row.sql.length === 0) {\n  // skip schema display; use PRAGMA table_info(tableName) instead\n}","typeGuard":"function hasSchemaText(row: { sql: string | null } | undefined): row is { sql: string } {\n  return typeof row?.sql === \"string\" && row.sql.length > 0;\n}","tryCatchPattern":"try {\n  const schema = getTableSchema(db, table);\n} catch (err) {\n  if (err instanceof ToolError && err.message.includes(\"is unavailable\")) {\n    const cols = db.query(`PRAGMA table_info(${quoteSqliteIdentifier(table)})`).all();\n    // synthesize schema from column info\n  } else throw err;\n}","preventionTips":["Only request schema for user tables (name NOT LIKE 'sqlite_%'), not internal/auto-index objects","Check sqlite_master.type === 'table' before fetching the CREATE statement","Fall back to PRAGMA table_info for objects without stored SQL"],"tags":["sqlite","schema","internal-object"],"backgroundTag":"schema-unavailable","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}