{"record":{"id":"6a1099ed0a493038","repo":"agalwood/Motrix","slug":"inherited-schema-missing","errorCode":"inherited_schema_missing","errorMessage":"The versioned database schema is incompatible with this build: expected canonical schema-version, plugin-state, and transfer tables, columns, constraints, primary keys, indexes, and trigger policy are invalid. This unpublished build updates the canonical v1 schema directly, so an existing local development database can have a valid version marker while its substantive tables are stale.\n\nAction: delete the database file and restart the app to recreate it on the current v1 schema.\n  rm '${dbPath}'","messagePattern":"The versioned database schema is incompatible with this build: expected canonical schema-version, plugin-state, and transfer tables, columns, constraints, primary keys, indexes, and trigger policy are invalid\\. This unpublished build updates the canonical v1 schema directly, so an existing local development database can have a valid version marker while its substantive tables are stale\\.\n\nAction: delete the database file and restart the app to recreate it on the current v1 schema\\.\n  rm '(.+?)'","errorType":"exception","errorClass":"StaleSchemaError","httpStatus":null,"severity":"critical","filePath":"src/core/session/migrations/index.ts","lineNumber":173,"sourceCode":"             type = 'trigger'\n             OR (type = 'index' AND sql IS NOT NULL)\n           )`\n      )\n      .all(...tables).length === 0\n  )\n}\n\nfunction hasExactCanonicalInheritedSchema(db: Database.Database): boolean {\n  if (!hasExactSchemaObjects(db, INHERITED_SCHEMA_OBJECTS)) {\n    return false\n  }\n\n  return hasNoExplicitIndexesOrTriggers(db, INHERITED_TABLES)\n}\n\nfunction assertCanonicalInheritedSchema(db: Database.Database): void {\n  if (!hasExactCanonicalInheritedSchema(db)) {\n    throw new StaleSchemaError(\n      'inherited_schema_missing',\n      (db as unknown as { name: string }).name\n    )\n  }\n}\n\nfunction assertCanonicalSchemaVersion(db: Database.Database): void {\n  if (\n    !hasExactSchemaObjects(db, SCHEMA_VERSION_OBJECTS) ||\n    !hasNoExplicitIndexesOrTriggers(db, ['schema_version'])\n  ) {\n    throw new StaleSchemaError(\n      'inherited_schema_missing',\n      (db as unknown as { name: string }).name\n    )\n  }\n}\n","sourceCodeStart":155,"sourceCodeEnd":191,"githubUrl":"https://github.com/agalwood/Motrix/blob/1a708ee57746c434e2c67a44bbf0906a976afea4/src/core/session/migrations/index.ts#L155-L191","documentation":"StaleSchemaError with reason 'inherited_schema_missing', thrown by assertCanonicalInheritedSchema() when the canonical schema_version + plugin-state + transfer tables' DDL, columns, constraints, PK order, indexes, and trigger policy do not EXACTLY match the expected INHERITED_SCHEMA_OBJECTS. This unpublished build edits the canonical v1 schema in place, so the version marker can be valid while the tables are stale.","triggerScenarios":"assertCanonicalInheritedSchema(db) returns false because hasExactSchemaObjects(db, INHERITED_SCHEMA_OBJECTS) fails OR hasNoExplicitIndexesOrTriggers(db, INHERITED_TABLES) finds extra triggers/indexes. Called from validateCanonicalV3 (post-migration, line 234) and from Guard B (line 388).","commonSituations":"Local dev DB from an older PR that created the inherited tables with a slightly different DDL (extra column, different PK order, modified CHECK); a manual ALTER TABLE during debugging that left an extra trigger; an older build that created an explicit index on a table this build expects to have none.","solutions":["Delete the dev database file (path is in dbPath in the message) and restart the app to recreate on the current v1 schema.","If you need the data, export it first, then delete and re-import on the fresh schema.","Avoid hand-editing the schema; if you ALTER during debugging, drop and recreate the DB before the next run."],"exampleFix":"# before: stale dev DB causing throw\n# after\n  rm '/path/to/session.db'\n# restart the app — migrate() will build the current v1 schema from scratch","handlingStrategy":"try-catch","validationCode":null,"typeGuard":"import { StaleSchemaError } from '@core/session/migrations';\nfunction isStaleSchemaError(e: unknown): e is StaleSchemaError {\n  return e instanceof StaleSchemaError;\n}","tryCatchPattern":"try {\n  migrate(db);\n} catch (e) {\n  if (e instanceof StaleSchemaError && e.reason === 'inherited_schema_missing') {\n    // dev-only: prompt user to reset DB; in CI fail fast\n    console.error(`Reset required: rm '${e.dbPath}'`);\n  } else throw e;\n}","preventionTips":["Treat the dev DB as ephemeral — delete it when switching branches.","Never hand-ALTER the inherited schema; let migrate() own it.","In tests, use a fresh in-memory DB per test rather than a shared file."],"tags":["database","sqlite","migration","schema","stale-schema"],"backgroundTag":null,"analyzedSha":"1a708ee57746c434e2c67a44bbf0906a976afea4","analyzedAt":"2026-08-12T16:18:09.346Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}