nexu-io/open-design · warning · LiveArtifactRefreshUnavailableError

Refresh is disabled for this artifact source.

Error message

Refresh is disabled for this artifact source.

What it means

refreshLiveArtifact (refresh-service.ts:161-162) throws LiveArtifactRefreshUnavailableError with this message when the source IS supported (passes isSupportedSource) but source.refreshPermission !== 'manual_refresh_granted_for_read_only' (hasRefreshPermission returns false). The source exists but explicit manual-refresh consent was never granted for the read-only source.

Source

Thrown at apps/daemon/src/live-artifacts/refresh-service.ts:162

      refreshId,
      now: refreshStartedAt,
    });
    await options.onStarted?.({ refreshId, artifact: running.artifact });

    try {
      const record = await getLiveArtifact(options);
      const artifact = record.artifact;
      const currentDataJson = artifact.document?.dataJson ?? {};
      const documentSource = artifact.document?.sourceJson;
      const hasDocumentSource = isSupportedSource(documentSource);
      const timeouts = normalizeLiveArtifactRefreshTimeouts();

      if (!hasDocumentSource) {
        throw new LiveArtifactRefreshUnavailableError();
      }

      if (!hasRefreshPermission(documentSource)) {
        throw new LiveArtifactRefreshUnavailableError('Refresh is disabled for this artifact source.');
      }

      const candidate = await withLiveArtifactRefreshRun(
        liveArtifactRefreshRunRegistry,
        {
          projectId: options.projectId,
          artifactId: options.artifactId,
          refreshId,
          totalTimeoutMs: timeouts.totalTimeoutMs,
          now: refreshStartedAt,
        },
        async (run) => {
          let documentOutput: { output: BoundedJsonObject } | undefined;
          if (hasDocumentSource) {
            const step = 'document';
            const sourceMetadata = documentSourceMetadata(documentSource);
            const documentStartedAt = nowDate();
            await appendLog({ step, status: 'running', startedAt: documentStartedAt, source: sourceMetadata });

View on GitHub (pinned to 5be4028344)

Solutions

  1. Grant manual refresh permission for the source (set refreshPermission to 'manual_refresh_granted_for_read_only').
  2. Re-add the source through the consent-granting flow so the permission flag is stamped.
  3. If you control artifact creation, set refreshPermission at the same time you attach sourceJson.
Defensive patterns

Strategy: validation

Validate before calling

const REFRESH_GRANTED = 'manual_refresh_granted_for_read_only';
function isRefreshPermitted(source: { refreshPermission?: string }): boolean {
  return source.refreshPermission === REFRESH_GRANTED;
}
if (!isRefreshPermitted(source)) {
  // drive the user through the consent-granting flow first
}

Type guard

function hasManualRefreshConsent(source: unknown): boolean {
  return typeof source === 'object' && source !== null
    && (source as { refreshPermission?: string }).refreshPermission === 'manual_refresh_granted_for_read_only';
}

Try / catch

try {
  await refreshLiveArtifact(opts);
} catch (err) {
  if (err instanceof LiveArtifactRefreshUnavailableError
      && err.message === 'Refresh is disabled for this artifact source.') {
    // prompt the user to grant manual refresh permission
    return;
  }
  throw err;
}

Prevention

When it happens

Trigger: A refresh-capable source (local_file/daemon_tool/connector_tool) exists on the artifact, but source.refreshPermission is undefined or set to a value other than 'manual_refresh_granted_for_read_only'.

Common situations: A connector or file source was attached without going through the consent-granting UI; the permission field was dropped during a data migration; an external/connector source that requires explicit user consent for read-only refresh.

Related errors


AI-assisted analysis of nexu-io/open-design@5be4028344 (2026-08-12). Data as JSON: /api/errors/ab5a5e5f2ea11f1b. Report an issue: GitHub.