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
- Before calling, ensure exactly one of bytes / text / absPath is set (and absPath is a non-empty existing file).
- Validate the input at the call site and throw a more specific error pointing at the caller.
- 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
- Always attach exactly one of bytes/text/absPath at the call site.
- If absPath is computed, ensure it is a non-empty existing file before passing.
- Treat this as a programmer error, not a runtime/retry condition.
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
- invalid JSON in ${filePath}: ${message}
- ${filePath} must contain a JSON object
- ARTIFACT_MANIFEST_INVALID
- ARTIFACT_MANIFEST_REQUIRED
- ARTIFACT_PUBLICATION_BLOCKED
AI-assisted analysis of nexu-io/open-design@5be4028344 (2026-08-12).
Data as JSON: /api/errors/bfe07d038460c074.
Report an issue: GitHub.