langgenius/dify · error · BaseError
usage_missing_arg
usage_missing_arg
Error message
specify a device label / id, or pass --all
What it means
Raised by DatasetMetadataBuiltInFieldActionApi.post (POST /datasets/{dataset_id}/metadata/built-in/{action}) when DatasetService.get_dataset returns None. Note this lookup is by id only (NOT tenant-scoped), so a cross-tenant dataset row that exists would pass this check and only later be filtered by check_dataset_permission. action must be 'enable' or 'disable'. Maps to HTTP 404.
Source
Thrown at cli/src/commands/auth/devices/_shared/devices.ts:83
}
return out
}
export type DevicesRevokeOptions = {
readonly io: IOStreams
readonly reg: Registry
readonly active: ActiveContext
readonly store: TokenStore
readonly http: HttpClient
readonly target?: string
readonly all: boolean
readonly yes?: boolean
}
export async function runDevicesRevoke(opts: DevicesRevokeOptions): Promise<void> {
const cs = colorScheme(colorEnabled(opts.io.isErrTTY))
if (!opts.all && (opts.target === undefined || opts.target === '')) {
throw new BaseError({
code: ErrorCode.UsageMissingArg,
message: 'specify a device label / id, or pass --all',
hint: "see 'difyctl auth devices list'",
})
}
const sessions = new AccountSessionsClient(opts.http)
const rows = await listAllSessions(sessions)
const { ids, selfHit } = pickTargets(rows, opts, opts.active.ctx.token_id ?? '')
if (ids.length === 0) {
opts.io.out.write('no sessions to revoke\n')
return
}
if (opts.yes !== true && opts.io.isErrTTY) {
const confirmed = await promptConfirm(opts.io, `Revoke ${ids.length} session(s)? [y/N] `)
if (!confirmed) {
throw new BaseError({View on GitHub (pinned to ef8544b173)
Solutions
- Verify the dataset exists via GET /datasets/{dataset_id} before toggling built-in fields.
- Refresh the dataset list to obtain a current ID.
- Guard the client so a 404 disables the toggle UI instead of retrying.
Example fix
// before
await post(`/datasets/${datasetId}/metadata/built-in/enable`);
// after
if (!(await get(`/datasets/${datasetId}`)).ok) { notify('Dataset missing'); return; }
await post(`/datasets/${datasetId}/metadata/built-in/enable`); Defensive patterns
Strategy: validation
Validate before calling
if (!(await datasetExists(client, datasetId))) {
throw new Error(`Cannot toggle built-in field: dataset ${datasetId} missing`);
} Type guard
type BuiltInAction = 'enable' | 'disable';
function isBuiltInAction(a: string): a is BuiltInAction { return a === 'enable' || a === 'disable'; } Try / catch
try {
await client.post(`/datasets/${datasetId}/metadata/built-in/${action}`);
} catch (e) {
if (e.response?.status === 404) { await refreshDatasetList(); return; }
throw e;
} Prevention
- Validate the dataset exists before toggling built-in fields.
- Note this endpoint uses id-only lookup; tenant scoping is enforced later by check_dataset_permission.
- Disable the toggle UI on 404 rather than retrying.
When it happens
Trigger: POST /console/api/datasets/{dataset_id}/metadata/built-in/enable (or disable) with a dataset_id that has no row at all. The action path parameter is validated by the Literal type only on the matched route, so an invalid action yields a routing/422 error, not this 404.
Common situations: Stale dataset_id after deletion; enabling/disabling built-in metadata fields on a dataset whose ID was hardcoded in a script that has drifted from the live data.
Related errors
- unknown
- export response missing data field
- reconnect stream body missing
- usage_missing_arg
- not_logged_in
AI-assisted analysis of langgenius/dify@ef8544b173 (2026-08-12).
Data as JSON: /api/errors/afe867be082be59c.
Report an issue: GitHub.