{"record":{"id":"2736a98fb2cab1a1","repo":"nexu-io/open-design","slug":"no-refresh-source-is-available-yet","errorCode":null,"errorMessage":"No refresh source is available yet.","messagePattern":"No refresh source is available yet\\.","errorType":"exception","errorClass":"LiveArtifactRefreshUnavailableError","httpStatus":null,"severity":"warning","filePath":"apps/daemon/src/live-artifacts/refresh-service.ts","lineNumber":158,"sourceCode":"    const running = await markLiveArtifactRefreshRunning({\n      projectsRoot: options.projectsRoot,\n      projectId: options.projectId,\n      artifactId: options.artifactId,\n      refreshId,\n      now: refreshStartedAt,\n    });\n    await options.onStarted?.({ refreshId, artifact: running.artifact });\n\n    try {\n      const record = await getLiveArtifact(options);\n      const artifact = record.artifact;\n      const currentDataJson = artifact.document?.dataJson ?? {};\n      const documentSource = artifact.document?.sourceJson;\n      const hasDocumentSource = isSupportedSource(documentSource);\n      const timeouts = normalizeLiveArtifactRefreshTimeouts();\n\n      if (!hasDocumentSource) {\n        throw new LiveArtifactRefreshUnavailableError();\n      }\n\n      if (!hasRefreshPermission(documentSource)) {\n        throw new LiveArtifactRefreshUnavailableError('Refresh is disabled for this artifact source.');\n      }\n\n      const candidate = await withLiveArtifactRefreshRun(\n        liveArtifactRefreshRunRegistry,\n        {\n          projectId: options.projectId,\n          artifactId: options.artifactId,\n          refreshId,\n          totalTimeoutMs: timeouts.totalTimeoutMs,\n          now: refreshStartedAt,\n        },\n        async (run) => {\n          let documentOutput: { output: BoundedJsonObject } | undefined;\n          if (hasDocumentSource) {","sourceCodeStart":140,"sourceCodeEnd":176,"githubUrl":"https://github.com/nexu-io/open-design/blob/5be4028344c2eb4c667c5a97bda8f750c5597ef7/apps/daemon/src/live-artifacts/refresh-service.ts#L140-L176","documentation":"refreshLiveArtifact (refresh-service.ts:154-158) throws LiveArtifactRefreshUnavailableError (default message) when the artifact's document has no sourceJson or its source.type is not one of the supported refresh types (checked via isSupportedSource). This signals that refresh is not possible for this artifact, as opposed to a refresh that ran and failed.","triggerScenarios":"Calling refreshLiveArtifact on an artifact where artifact.document.sourceJson is undefined, or where sourceJson.type is not 'local_file', 'daemon_tool', or 'connector_tool'.","commonSituations":"The artifact was created without a refresh source (e.g. a static document); the sourceJson was stripped or never persisted; a legacy artifact predates the live-artifact refresh feature; the document was authored by hand/imported without source metadata.","solutions":["Ensure the artifact's document.sourceJson is present and uses a supported type before triggering refresh.","Recreate or re-import the artifact through a flow that attaches a refresh-capable source.","Treat LiveArtifactRefreshUnavailableError in the UI/CLI as a soft state ('refresh unavailable') rather than an error toast."],"exampleFix":null,"handlingStrategy":"type-guard","validationCode":"import { isSupportedSource } from './refresh-service.js'; // conceptually\nfunction canRefresh(artifact: { document?: { sourceJson?: unknown } }): boolean {\n  return isSupportedSource(artifact.document?.sourceJson as never);\n}\nif (!canRefresh(artifact)) {\n  // show 'refresh unavailable' state instead of triggering a refresh\n}","typeGuard":"function hasRefreshableDocumentSource(source: unknown): source is { type: string; refreshPermission?: string } {\n  if (typeof source !== 'object' || source === null) return false;\n  const t = (source as { type?: string }).type;\n  return t === 'local_file' || t === 'daemon_tool' || t === 'connector_tool';\n}","tryCatchPattern":"try {\n  await refreshLiveArtifact(opts);\n} catch (err) {\n  if (err instanceof LiveArtifactRefreshUnavailableError) {\n    // render as a soft 'no refresh source' state, not a hard error\n    return;\n  }\n  throw err;\n}","preventionTips":["Always attach a supported document.sourceJson when creating a live artifact meant to refresh.","Treat LiveArtifactRefreshUnavailableError distinctly from generic Errors in the UI.","Before exposing a refresh button, check isSupportedSource on the artifact's source."],"tags":["live-artifacts","refresh","unavailable","source-type"],"backgroundTag":null,"analyzedSha":"5be4028344c2eb4c667c5a97bda8f750c5597ef7","analyzedAt":"2026-08-12T12:03:58.812Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}