nexu-io/open-design · error

registerLibraryAsset requires bytes, text, or absPath

Error message

registerLibraryAsset requires bytes, text, or absPath

What it means

Raised by registerLibraryAsset() when none of input.bytes, input.text, or input.absPath produced a Buffer. The function accepts three payload shapes (raw bytes, utf-8 text, or a file to read) and treats the absence of all three as a caller contract violation rather than silently registering an empty asset.

Source

Thrown at apps/daemon/src/library.ts:339

 * are written content-addressed under LIBRARY_DIR; referenced assets only
 * store a pointer. Always appends a source record for the back-link graph.
 */
export async function registerLibraryAsset(
  input: RegisterLibraryAssetInput,
): Promise<RegisterLibraryAssetResult> {
  const { db, libraryDir } = input;

  let bytes = input.bytes ?? null;
  let mime = input.mime;
  if (!bytes && typeof input.text === 'string') {
    bytes = Buffer.from(input.text, 'utf8');
    if (!mime) mime = 'text/plain';
  }
  if (!bytes && input.absPath) {
    bytes = await readFile(input.absPath);
  }
  if (!bytes) {
    throw new Error('registerLibraryAsset requires bytes, text, or absPath');
  }

  const contentHash = createHash('sha256').update(bytes).digest('hex');

  // Dedup: same bytes already indexed → append source, union tags.
  const existing = findLibraryAssetByHash(db, contentHash);
  if (existing) {
    return dedupIntoExistingAsset(db, existing, input);
  }

  if (!mime) mime = detectMime(bytes, input.filename);
  const kind = input.kind ?? kindForMime(mime);
  const dims = kind === 'image' ? sniffImageDimensions(bytes) : null;
  const now = Date.now();
  // The artifact's own time (DS update / file mtime) when the caller supplies
  // it, so the timeline buckets by creation rather than sync time; else now.
  const capturedAt = Number.isFinite(input.capturedAt) ? Number(input.capturedAt) : now;
  const id = randomUUID();

View on GitHub (pinned to 5be4028344)

Solutions

  1. Before calling, ensure exactly one of bytes / text / absPath is set (and absPath is a non-empty existing file).
  2. Validate the input at the call site and throw a more specific error pointing at the caller.
  3. If the caller only has a URL, download to bytes first, then pass bytes.

Example fix

// before
await registerLibraryAsset({ db, libraryDir, storage, source, mime, filename });

// after
await registerLibraryAsset({
  db, libraryDir, storage, source,
  bytes: await readFile(localFilePath),
  mime, filename,
});
Defensive patterns

Strategy: validation

Validate before calling

import type { RegisterLibraryAssetInput } from '../library.js';

function hasRegisterablePayload(input: RegisterLibraryAssetInput): boolean {
  return Boolean(input.bytes || (typeof input.text === 'string' && input.text) || input.absPath);
}

if (!hasRegisterablePayload(input)) {
  throw new Error('caller: registerLibraryAsset needs one of bytes/text/absPath');
}

Type guard

function isRegisterableInput(input: RegisterLibraryAssetInput): input is RegisterLibraryAssetInput & { bytes: Buffer } {
  return Boolean(input.bytes) || typeof input.text === 'string' || Boolean(input.absPath);
}

Try / catch

try {
  return await registerLibraryAsset(input);
} catch (err) {
  if (err instanceof Error && err.message === 'registerLibraryAsset requires bytes, text, or absPath') {
    // caller bug — fix the call site, do not retry
    throw new Error('caller did not provide asset payload');
  }
  throw err;
}

Prevention

When it happens

Trigger: A caller builds RegisterLibraryAssetInput with source/metadata but forgets to attach bytes/text/absPath; absPath was set but the file did not exist (readFile would throw earlier) or absPath was an empty string (falsy, so the branch was skipped).

Common situations: Refactor that stopped passing bytes; conditional payload building that leaves all three undefined for an edge case; caller assumes mime/filename implies content; absPath set to '' after a bad path sanitization step.

Related errors


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