Skip to content

Commit 12cb872

Browse files
committed
fix(mcp): route dependency-blocked fields to failed[] in deleteFields; add test
1 parent 5a8cfef commit 12cb872

2 files changed

Lines changed: 39 additions & 1 deletion

File tree

packages/mcp-server/src/client.js

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -708,7 +708,11 @@ export class AirtableClient {
708708
const { fieldId, expectedName } = fields[i];
709709
try {
710710
const result = await this.deleteField(appId, fieldId, expectedName, { force });
711-
succeeded.push({ fieldId, name: expectedName, deleted: result.deleted, forced: result.forced ?? false });
711+
if (!result.deleted) {
712+
failed.push({ fieldId, name: expectedName, error: result.message ?? 'Field was not deleted' });
713+
} else {
714+
succeeded.push({ fieldId, name: expectedName, deleted: true, forced: result.forced ?? false });
715+
}
712716
} catch (error) {
713717
failed.push({ fieldId, name: expectedName, error: error.message });
714718
}

packages/mcp-server/test/test-bulk-delete.test.js

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,4 +150,38 @@ describe('AirtableClient.deleteFields', () => {
150150
assert.equal(result.succeeded.length, 1);
151151
assert.equal(result.failed.length, 1);
152152
});
153+
154+
it('routes deleted:false (dependency-blocked) to failed[] when force=false', async () => {
155+
const DEPENDENCY_RESPONSE = {
156+
ok: false,
157+
status: 400,
158+
json: async () => ({
159+
error: {
160+
type: 'SCHEMA_DEPENDENCIES_VALIDATION_FAILED',
161+
details: { dependentColumns: [{ id: 'fldDEP', type: 'formula' }] },
162+
},
163+
}),
164+
text: async () => JSON.stringify({ error: { type: 'SCHEMA_DEPENDENCIES_VALIDATION_FAILED' } }),
165+
};
166+
const auth = createMockAuth({
167+
get() {
168+
return {
169+
ok: true, status: 200,
170+
json: async () => ({
171+
data: { tableSchemas: [{ id: 'tbl1', columns: [{ id: 'fld001', name: 'HasDeps', type: 'formula', typeOptions: {} }], views: [] }] },
172+
}),
173+
text: async () => '{}',
174+
};
175+
},
176+
postForm() {
177+
return DEPENDENCY_RESPONSE;
178+
},
179+
});
180+
const client = new AirtableClient(auth);
181+
const result = await client.deleteFields('appTEST', [{ fieldId: 'fld001', expectedName: 'HasDeps' }], { force: false });
182+
assert.equal(result.succeeded.length, 0, 'no fields should be in succeeded');
183+
assert.equal(result.failed.length, 1, 'dependency-blocked field should be in failed');
184+
assert.ok(result.failed[0].error.includes('dependencies') || result.failed[0].error.includes('not deleted'),
185+
`error message should mention dependencies or not deleted, got: "${result.failed[0].error}"`);
186+
});
153187
});

0 commit comments

Comments
 (0)