moeru-ai/airi · error · Error
Invalid duration format: ${duration}
Error message
Invalid duration format: ${duration} What it means
Thrown by parseWindowDuration() in the temporal perception detector. It parses a duration string into milliseconds using the regex /^(\d+(?:\.\d+)?)(ms|s|m)?$/. Supported formats: bare number (treated as ms), 'NNms', 'NNs', 'NNm'. Anything that does not match — letters without a number, unsupported units (h, d), spaces, negative numbers, multiple units — throws with the offending input echoed.
Source
Thrown at integrations/minecraft/src/cognitive/perception/rules/temporal-detector.ts:229
export function processEvent(
state: DetectorState,
input: ProcessDetectorInput,
): readonly [boolean, DetectorState] {
if (input.mode === 'tumbling') {
return processTumblingEvent(state, input)
}
return processSlidingEvent(state, input)
}
/**
* Parse window duration string to milliseconds
* Supports: '2s', '500ms', '1m', '100'
*/
export function parseWindowDuration(duration: string): number {
const match = duration.match(/^(\d+(?:\.\d+)?)(ms|s|m)?$/)
if (!match) {
throw new Error(`Invalid duration format: ${duration}`)
}
const value = Number.parseFloat(match[1])
const unit = match[2] || 'ms'
switch (unit) {
case 'ms': return value
case 's': return value * 1000
case 'm': return value * 60 * 1000
default: return value
}
}
/**
* Calculate number of slots for a given window duration
*/
export function calculateWindowSlots(
windowMs: number,View on GitHub (pinned to 27111382b4)
Solutions
- Use one of the supported formats: '500ms', '2s', '1m', or a bare number (milliseconds).
- Normalise user/config input to the supported units before calling parseWindowDuration.
- If you need hours/days, convert to minutes or milliseconds upstream (e.g. 2h -> 120m).
- Trim whitespace and validate non-empty before parsing.
Example fix
// before
// parseWindowDuration('1h') // throws
// parseWindowDuration('5 s') // throws
//
// after
// parseWindowDuration('60m') // ok -> 3600000
// parseWindowDuration('5s') // ok -> 5000 Defensive patterns
Strategy: validation
Validate before calling
import { parseWindowDuration } from './temporal-detector'
const DURATION_RE = /^(\d+(?:\.\d+)?)(ms|s|m)?$/
export function safeParseDuration(input: string): number | null {
const s = input.trim()
if (!DURATION_RE.test(s)) return null
return parseWindowDuration(s)
}
// const ms = safeParseDuration(userInput)
// if (ms === null) { /* reject the config value */ } Type guard
function isDurationString(v: unknown): v is string {
return typeof v === 'string' && /^\d+(?:\.d+)?(?:ms|s|m)?$/.test(v.trim())
} Prevention
- Restrict durations to 'NNms', 'NNs', 'NNm', or a bare millisecond number.
- Trim and reject empty input before parsing.
- Convert hours/days to minutes or ms upstream; this parser does not accept h/d.
- Validate config-supplied durations at load time, not at first event.
When it happens
Trigger: Passing '1h', '2d', '-5s', '5 seconds', 'abc', '5s5', '5 s', or a value with a unit the regex does not recognise; passing an empty string; passing a value with a trailing space or newline that breaks the anchored regex.
Common situations: Config typo in a detector rule window; user-supplied duration from a chat command parsed without normalisation; unit confusion (caller assumes '100' means seconds but the default unit is ms); copying a duration from a tool that uses 'h'/'d'.
Related errors
- Artistry provider is disabled.
- Provider '${requestedProvider}' not found.
- Nano Banana API Key not configured
- Output does not contain a recognizable image URL.
- Invalid JSON for componentProps: ${(error as Error).message}
AI-assisted analysis of moeru-ai/airi@27111382b4 (2026-08-12).
Data as JSON: /api/errors/ec31696bc8331dd5.
Report an issue: GitHub.