different-ai/openwork · error · RemoteMcpAppError
app_retired
app_retired
Error message
Restore this app before activating a revision.
What it means
activateRemoteMcpAppRevision refuses to operate on retired apps. If app.status === 'retired', activating a revision is rejected with 409 app_retired; the app must first be restored (setRemoteMcpAppRetired with retired:false). This keeps retirement a blocking state.
Source
Thrown at ee/apps/den-api/src/remote-mcp-apps.ts:542
})
const updatedAt = new Date()
await db.update(RemoteMcpAppTable).set({
sourceUrl: fetched.sourceUrl,
resolvedSourceUrl: fetched.resolvedSourceUrl,
updatedAt,
}).where(eq(RemoteMcpAppTable.configObjectId, app.configObjectId))
const updated = { ...app, sourceUrl: fetched.sourceUrl, resolvedSourceUrl: fetched.resolvedSourceUrl, updatedAt }
return serializeApp(updated, "editor")
}
export async function activateRemoteMcpAppRevision(input: {
context: PluginArchActorContext
configObjectId: string
versionId: string
}) {
const app = await getAppRow(input.context, input.configObjectId, "editor")
if (app.status === "retired") {
throw new RemoteMcpAppError(409, "app_retired", "Restore this app before activating a revision.")
}
let versionId: DenTypeId<"configObjectVersion">
try {
versionId = normalizeDenTypeId("configObjectVersion", input.versionId)
} catch {
throw new RemoteMcpAppError(404, "app_revision_not_found", "App revision not found.")
}
const versions = await db.select().from(ConfigObjectVersionTable).where(and(
eq(ConfigObjectVersionTable.configObjectId, app.configObjectId),
eq(ConfigObjectVersionTable.id, versionId),
eq(ConfigObjectVersionTable.isDeletedVersion, false),
)).limit(1)
const version = versions[0]
if (!version || !version.rawSourceText) throw new RemoteMcpAppError(404, "app_revision_not_found", "App revision not found.")
const payload = parseVersionPayload(version)
if (sha256(version.rawSourceText) !== payload.resource.digest) {
throw new RemoteMcpAppError(422, "cached_app_digest_mismatch", "The cached app revision failed its integrity check.")
}View on GitHub (pinned to 2b7df46e8a)
Solutions
- Restore the app first: setRemoteMcpAppRetired({ context, configObjectId, retired: false }) with manager role.
- Then call activateRemoteMcpAppRevision with the desired versionId.
- If the app should stay retired, do not schedule activation work for it.
Example fix
// before
await activateRemoteMcpAppRevision({ context, configObjectId, versionId })
// after
await setRemoteMcpAppRetired({ context, configObjectId, retired: false })
await activateRemoteMcpAppRevision({ context, configObjectId, versionId }) Defensive patterns
Strategy: validation
Validate before calling
const app = await getRemoteMcpApp({ context, configObjectId })
if (app.status === 'retired') throw new Error('Restore the app before activating a revision') Type guard
function isActivatable(app: { status: string }): boolean {
return app.status !== 'retired'
} Try / catch
try { await activateRemoteMcpAppRevision({ context, configObjectId, versionId }) } catch (e) {
if (e instanceof RemoteMcpAppError && e.code === 'app_retired') {
await setRemoteMcpAppRetired({ context, configObjectId, retired: false })
// then retry activation
}
} Prevention
- Check app.status before scheduling activation work
- Skip retired apps in CI/automation pipelines
- Restore via setRemoteMcpAppRetired({retired:false}) as an explicit step
When it happens
Trigger: Calling activateRemoteMcpAppRevision for an app whose RemoteMcpAppTable.status is 'retired' (previously retired via setRemoteMcpAppRetired({retired:true})).
Common situations: Retrying an activation script after the app was retired; CI pipelines activating revisions on apps decommissioned by an admin.
Related errors
- app_has_no_active_revision
- error.code
- github_connector_app_not_configured
- github_connector_request_failed
AI-assisted analysis of different-ai/openwork@2b7df46e8a (2026-09-01).
Data as JSON: /api/errors/91be601061cabb51.
Report an issue: GitHub.