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

  1. Activate a revision first via activateRemoteMcpAppRevision with a valid versionId, then refresh.
  2. If you intended the app active, re-import without activate:false so an active revision is set at import time.
  3. 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

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.