different-ai/openwork · error · RemoteMcpAppError
app_has_no_active_revision
app_has_no_active_revision
Error message
Activate an app revision before caching an update.
What it means
refreshRemoteMcpApp caches a new revision from the remote source, but that only makes sense when the app has an active revision baseline. If app.activeVersionId is null (imported with activate:false or never activated), it throws 409 app_has_no_active_revision before any fetch or version write.
Source
Thrown at ee/apps/den-api/src/remote-mcp-apps.ts:507
}
await db.insert(RemoteMcpAppTable).values(app)
return serializeApp(app, "manager")
}
export async function getRemoteMcpApp(input: { context: PluginArchActorContext; configObjectId: string }) {
const app = await getAppRow(input.context, input.configObjectId)
const role = await resolvePluginArchResourceRole({ context: input.context, resourceId: app.configObjectId, resourceKind: "config_object" })
if (!role) throw new RemoteMcpAppError(404, "remote_app_not_found", "Remote MCP App not found.")
return serializeApp(app, role)
}
export async function refreshRemoteMcpApp(input: {
context: PluginArchActorContext
configObjectId: string
sourceUrl?: string
}) {
const app = await getAppRow(input.context, input.configObjectId, "editor")
if (!app.activeVersionId) throw new RemoteMcpAppError(409, "app_has_no_active_revision", "Activate an app revision before caching an update.")
const activeVersions = await db.select().from(ConfigObjectVersionTable).where(and(
eq(ConfigObjectVersionTable.configObjectId, app.configObjectId),
eq(ConfigObjectVersionTable.id, app.activeVersionId),
eq(ConfigObjectVersionTable.isDeletedVersion, false),
)).limit(1)
if (!activeVersions[0]) throw new RemoteMcpAppError(404, "app_revision_not_found", "The active app revision was not found.")
const fetched = await fetchRemoteMcpApp(input.sourceUrl ?? app.sourceUrl)
await createConfigObjectVersion({
context: input.context,
configObjectId: app.configObjectId,
reason: fetched.digest,
value: {
normalizedPayloadJson: payloadForFetchedApp(fetched) as unknown as Record<string, unknown>,
rawSourceText: fetched.html,
schemaVersion: REMOTE_MCP_APP_CONFIG_SCHEMA_VERSION,
},
})
const updatedAt = new Date()View on GitHub (pinned to 2b7df46e8a)
Solutions
- Activate a revision first via activateRemoteMcpAppRevision with a valid versionId, then refresh.
- If you intended the app active, re-import without activate:false so an active revision is set at import time.
- Skip null-active apps in refresh loops or treat them as pending activation.
Example fix
// before
await refreshRemoteMcpApp({ context, configObjectId })
// after
const app = await getRemoteMcpApp({ context, configObjectId })
if (!app.activeVersionId) {
await activateRemoteMcpAppRevision({ context, configObjectId, versionId: firstVersionId })
}
await refreshRemoteMcpApp({ context, configObjectId }) Defensive patterns
Strategy: validation
Validate before calling
const app = await getRemoteMcpApp({ context, configObjectId })
if (!app.activeVersionId) throw new Error('Activate a revision before refreshing') Type guard
function canRefresh(app: { activeVersionId: string | null }): app is { activeVersionId: string } {
return app.activeVersionId !== null
} Try / catch
try { await refreshRemoteMcpApp({ context, configObjectId }) } catch (e) {
if (e instanceof RemoteMcpAppError && e.code === 'app_has_no_active_revision') {
// activate a revision first, then retry refresh
}
} Prevention
- Import apps with activate:true unless activation is intentionally deferred
- Track apps pending activation and exclude them from refresh jobs
- After import, verify activeVersionId is set before scheduling refreshes
When it happens
Trigger: Calling refreshRemoteMcpApp on an app whose activeVersionId is null — typically an app imported with activate:false that has never had a revision activated, or whose active revision was never set.
Common situations: Automated refresh jobs running over apps imported in deactivated mode; refreshing right after import when activation was deferred.
Related errors
AI-assisted analysis of different-ai/openwork@2b7df46e8a (2026-09-01).
Data as JSON: /api/errors/20a3911581b0403d.
Report an issue: GitHub.