Skip to content
Astera Technology

Why does a migration fail on a similarly named schema version?

Check the actual predecessor columns and supplied version before applying a step.

Download complete case notes and answer keys ↓

Read the source and its declared rule

The original step renames b to count only from versionV1 with columns a, b. A different branch has a, c despite the same supplied label. Blind ALTER fails on missing b; corrected preflight inspects table_info and holds the mismatching schema without mutation.

Filled synthetic input
RecordInput JSON
Base input{"branch":"AC","version":"V1"}
Download editable CSV ↓

Compare the actual paths

Good output explains schema-precondition rather than treating a source value as faulty. An unknown version remains held even if its columns happen to resemble the expected branch.

Misleading and corrected outputs
PathOutput JSON
Misleading path{"error":{"code":1},"columns":["a","c"],"records":[{"a":"A","c":2}]}
Corrected path{"error":"schema-precondition","columns":["a","c"],"records":[{"a":"A","c":2}]}
Download editable CSV ↓
Local Node.js program: 22.23.3 or 24.14.1
import {DatabaseSync} from 'node:sqlite';
import {TextDecoder} from 'node:util';
import {inflateSync} from 'node:zlib';
import {posix} from 'node:path';
import {createHash} from 'node:crypto';
const rows=(db,sql)=>db.prepare(sql).all().map(r=>({...r}));
const failed=(action)=>{try{action();return null;}catch(e){return {code:e.errcode??e.code??e.name};}};

import assert from 'node:assert/strict';
const run=function run(i,corrected=true){
    const db=new DatabaseSync(':memory:');try{db.exec('CREATE TABLE target(a TEXT,'+(i.branch==='AB'?'b':'c')+' INTEGER);');db.prepare('INSERT INTO target VALUES(?,?)').run('A',2);
      const columns=()=>db.prepare('PRAGMA table_info(target)').all().map(c=>c.name);let error=null;
      if(corrected&&(i.version!=='V1'||!columns().includes('b')))error=i.version===null?'unknown-version':'schema-precondition';
      else error=failed(()=>db.exec('ALTER TABLE target RENAME COLUMN b TO count;'));
      return {error,columns:columns(),records:rows(db,'SELECT * FROM target')};
    }finally{db.close();}
  };
const cases=[{"label":"misleading base","input":{"branch":"AC","version":"V1"},"expected":{"error":{"code":1},"columns":["a","c"],"records":[{"a":"A","c":2}]},"corrected":false},{"label":"corrected base","input":{"branch":"AC","version":"V1"},"expected":{"error":"schema-precondition","columns":["a","c"],"records":[{"a":"A","c":2}]},"corrected":true},{"label":"matching actual predecessor","input":{"branch":"AB","version":"V1"},"expected":{"error":null,"columns":["a","count"],"records":[{"a":"A","count":2}]},"corrected":true},{"label":"unknown version even with similar columns","input":{"branch":"AB","version":null},"expected":{"error":"unknown-version","columns":["a","b"],"records":[{"a":"A","b":2}]},"corrected":true}];
for(const test of cases){
  const actual=run(test.input,test.corrected);
  assert.deepEqual(actual,test.expected,test.label);
  console.log(test.label,actual);
}
Download runnable example ↓

Check boundaries before the next load

Exact a, b/V1 renames successfully. Null version leaves a, b untouched.

Editable boundary records and expected outputs
CaseInput JSONExpected output JSON
Exact predecessor branch{"branch":"AB","version":"V1"}{"error":null,"columns":["a","count"],"records":[{"a":"A","count":2}]}
Unknown predecessor version{"branch":"AB","version":null}{"error":"unknown-version","columns":["a","b"],"records":[{"a":"A","b":2}]}
Download editable CSV ↓

Does a version labelV1 prove this branch has columnb?

Show the worked answer

No. Inspect actual columns. The a, c fixture is held and stays unchanged.

Related resources