iflytek/astron-agent · error

未开始录音

Error message

未开始录音${isCtxWait ? ',开始录音前无用户交互导致AudioContext未运行' : ''}

What it means

Recorder-Core's stop() fails because recording never actually started: This.state is 0 (never opened/started) or 3 (open succeeded but the AudioContext is suspended because the browser requires a user gesture before audio processing). The isCtxWait suffix clarifies that user interaction was missing, so the AudioContext never left the 'suspended' state.

Solutions

  1. Ensure rec.start() is called inside a direct user-gesture handler (click/touchend) so the AudioContext resumes.
  2. Guard stop() calls: only invoke when recording state confirms start succeeded.
  3. If you defer start, prompt the user to interact (e.g. 'Tap to start recording') and call start() in that handler.
  4. Check mic permission was granted; a pending/denied permission can leave state unresolved.
  5. After resume() on the AudioContext, verify rec.state before stopping.

Example fix

// before
rec.open(function() { /* waiting... */ });
rec.stop(); // state==3 -> error

// after
rec.open(function() {
  startBtn.onclick = function() {
    rec.start();
  };
});
stopBtn.onclick = function() {
  if (rec.state === 1) rec.stop();
};
Defensive patterns

Strategy: validation

Validate before calling

function canStop(rec) {
  return rec && typeof rec.state === 'number' && rec.state === 1;
}
if (!canStop(rec)) return; // don't call stop unless recording

Type guard

function isRecording(rec) { return !!rec && rec.state === 1; }

Try / catch

try { rec.stop(onDone); } catch (e) {
  if (String(e).includes('未开始录音')) {
    showToast('Please start recording first (tap to allow audio)');
  }
}

Prevention

When it happens

Trigger: Calling Recorder.stop() when This.state is falsy (recorder never opened) or state==3; state 3 arises when rec.open() succeeded but rec.start() was deferred waiting for a user gesture and none occurred, leaving the browser AudioContext suspended.

Common situations: Calling stop() without a prior start(); attempting to auto-start recording on page load without a click/tap (Chrome/Safari autoplay policy); an async permission prompt consumed the gesture window; SPA navigated away before start was triggered.

Understand the failure class

Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.

Related errors


AI-assisted analysis of iflytek/astron-agent@5e758547a8 (2026-09-12). Data as JSON: /api/errors/43625beefb79db82. Report an issue: GitHub.

Appendix: source

Thrown at console/frontend/src/utils/record/recorder-core.js:1373

        if (set.takeoffEncodeChunk) {
          //接管了输出,此时blob长度为0
          This.CLog(
            '启用takeoffEncodeChunk后stop返回的blob长度为0不提供音频数据',
            3
          );
        } else if (blob.size < Math.max(100, duration / 2)) {
          //1秒小于0.5k?
          err('生成的' + set.type + '无效');
          return;
        }
        True &&
          True(blob, duration, originBUffers || [], originSampleRate || 44100);
        end();
      };
      if (!This.isMock) {
        var isCtxWait = This.state == 3;
        if (!This.state || isCtxWait) {
          err(
            '未开始录音' +
              (isCtxWait ? ',开始录音前无用户交互导致AudioContext未运行' : '')
          );
          return;
        }
        This._stop(true);
      }
      var size = This.recSize;
      if (!size) {
        err('未采集到录音');
        return;
      }
      if (!This.buffers[0]) {
        err('音频buffers被释放');
        return;
      }
      if (!This[set.type]) {
        err('未加载' + set.type + '编码器');

View on GitHub (pinned to 5e758547a8)