janhq/jan · error

Jan data folder is unavailable

Error message

Jan data folder is unavailable

What it means

Thrown by the agentWorkspace helper dataFolder() when getServiceHub().app().getJanDataFolder() resolves to an empty/undefined folder path. All workspace operations (storePath, memory CRUD) depend on this base path, so the error is raised eagerly rather than writing to an invalid location.

Solutions

  1. Ensure the app is fully initialized before invoking workspace/memory APIs
  2. Check that the Jan data folder is set in app settings and points to a valid directory
  3. Restart the app so getJanDataFolder() re-resolves the default path
  4. If the setting is corrupted, reset it to the default data directory

Example fix

// before
const path = await storePath()
// after
let path: string
try {
  path = await storePath()
} catch {
  path = await ensureDefaultWorkspace()
}
Defensive patterns

Strategy: try-catch

Validate before calling

const folder = await getServiceHub().app().getJanDataFolder()
if (!folder) throw new Error('Jan data folder is unavailable — check app settings or wait for initialization')

Type guard

const hasDataFolder = (f: unknown): f is string =>
  typeof f === 'string' && f.trim().length > 0

Try / catch

try {
  await writeMemory(key, value)
} catch (e) {
  if (e.message === 'Jan data folder is unavailable') {
    showToast('Workspace unavailable — the app is still initializing or the data folder is unset.')
  }
}

Prevention

When it happens

Trigger: Any call to storePath, listMemories, readMemory, writeMemory, or deleteMemory while the app service returns a falsy Jan data folder — typically during early startup before the app service is ready, or when the data folder setting is unset/failed to resolve.

Common situations: Calling workspace APIs before app initialization completes; the Jan data folder configuration was cleared; the app service failed to determine the default data directory (e.g. on first launch or after a failed migration).

Understand the failure class

Background: "missing required config value" errors: why libraries refuse to start when a configuration key is empty, unset, or blank — this error's family across 48 libraries.

Related errors


AI-assisted analysis of janhq/jan@7205d770c1 (2026-09-17). Data as JSON: /api/errors/0edd1e7e2aebe047. Report an issue: GitHub.

Appendix: source

Thrown at web-app/src/lib/agentWorkspace.ts:26

import { getServiceHub } from '@/hooks/useServiceHub'
import { invalidateMemory } from '@/lib/agentTools'
import * as skillStore from '@/lib/skillStore'
import type { SkillMeta } from '@/lib/skillStore'

export type { SkillMeta }

/**
 * The management surface over the agent's permanent store, for the settings UI.
 * Separate from `agentTools.ts`, which is the chat-loop surface: this one edits
 * what the agent remembers, that one executes what the model calls.
 *
 * Errors are thrown rather than swallowed. Unlike a tool call, a failed edit has
 * a user waiting on it, so the page surfaces it.
 */

const dataFolder = async (): Promise<string> => {
  const folder = await getServiceHub().app().getJanDataFolder()
  if (!folder) throw new Error('Jan data folder is unavailable')
  return folder
}

/** Path of the permanent store, created if absent. */
export async function storePath(): Promise<string> {
  return await workspacePath(await dataFolder())
}

// Skill CRUD is shared with the code screen's per-project skills; only the root
// differs. These bind this page to the permanent store.
export const listSkills = () => skillStore.listSkills(skillStore.storeScope)
export const readSkill = (name: string) =>
  skillStore.readSkill(skillStore.storeScope, name)
export const writeSkill = (name: string, content: string) =>
  skillStore.writeSkill(skillStore.storeScope, name, content)
export const deleteSkill = (name: string) =>
  skillStore.deleteSkill(skillStore.storeScope, name)

View on GitHub (pinned to 7205d770c1)