Skip to main content

FAQ (Frequently Asked Questions)

Based on React SDK documentation content and community feedback, the most important questions and solutions are compiled.

1. mount() Repeated Call Warning in Development Mode

Symptom: Console shows warning about repeated mount() calls

Cause: This is normal behavior of React StrictMode and React 19 in development mode. To help developers discover side effect issues, React intentionally executes useEffect twice.

Solution 1: Use Cleanup Function

useEffect(
() => {
if (controller && containerRef.current) {
controller.mount(containerRef.current);

return () => {
controller.dispose();
};
}
},
[controller]
);

Solution 2: Use ref to Track Mount State

const mountedRef = useRef(false);

useEffect(
() => {
if (controller && containerRef.current && !mountedRef.current) {
controller.mount(containerRef.current);
mountedRef.current = true;
}
},
[controller]
);
info

This issue only appears in development environment, and will not occur in production environment.

2. Provider Component Usage Pitfalls

Symptom: controller returned by useAaaSPilotKit is always null, or throws Context error

Cause: Component is not used inside AaaSPilotKitProvider, or Provider configuration is wrong

Solution:

// ❌ Error: Component outside Provider
function App() {
return (
<>
{/* Cannot access Context */}
<Dashboard />
<AaaSPilotKitProvider options={options}>
<ChatPanel />
</AaaSPilotKitProvider>
</>
);
}

// ✅ Correct: Ensure all components using Hooks are inside Provider
function App() {
return (
<AaaSPilotKitProvider options={options}>
<Dashboard />
<ChatPanel />
</AaaSPilotKitProvider>
);
}

Reference: Provider Context

3. Issues with Manual Controller Creation and Destruction

Symptom: Abnormal controller state, resources not properly released, or repeated creation

Cause: Improper lifecycle management when manually using create and dispose methods

Solution:

function PilotKit() {
const [isInactive, setIsInactive] = useState(false);
const {controller, create, dispose} = useAaaSPilotKit();

// ✅ Correct manual lifecycle management
const onInactivity = useCallback(
() => {
setIsInactive(true);
// Manually destroy controller
dispose();
},
[dispose]
);

const restart = useCallback(
() => {
setIsInactive(false);
// Manually re-create controller
create();
},
[create]
);

useAaaSPilotKitEvents({
onInactivity
});

if (isInactive) {
return (
<div>
Session timed out
<button onClick={restart}>
Restart
</button>
</div>
);
}

return <AvatarComponent />;
}

Key Points:

  • create() and dispose() are used for manual controller lifecycle management
  • After calling dispose(), need to create() again before using
  • Provider usually manages automatically, only manually control in special scenarios

Common Errors:

// ❌ Error: Forget to create after dispose
const handleTimeout = () => {
dispose();
// Missing create(), causing controller to be null
};

// ❌ Error: Repeated create
const handleRestart = () => {
create(); // May cause repeated creation
create(); // Repeated call
};

// ❌ Error: Use controller directly after dispose
dispose();
controller?.input('test'); // controller is already null

// ✅ Correct: Equivalent logic
useEffect(
() => {
create();

return dispose;
},
[]
);

Reference: Hooks API

4. Frequent Re-reconstruction Caused by options Configuration

Symptom: Controller frequently re-creates, or configuration updates don't take effect

Cause: options object reference is unstable, creating new object on every render

Solution:

// ❌ Error: Create new object on every render
function App() {
return (
<AaaSPilotKitProvider options={{
token: 'your-auth-token-here',
figureId: '209337',
agentConfig: {token: 'xxx', robotId: 'yyy'}
}}>
<Dashboard />
</AaaSPilotKitProvider>
);
}


// ✅ Correct: Use useMemo to stabilize reference
function App() {
const [robotId, setRobotId] = useState('default-robot');

const options = useMemo(
() => ({
token: 'your-auth-token-here',
figureId: '209337',
ttsPer: 'LITE_audiobook_female_1',
agentConfig: {
robotId: robotId
}
}),
// Only re-create when dependency changes
[robotId]
);

return (
<AaaSPilotKitProvider options={options}>
<Dashboard />
</AaaSPilotKitProvider>
);
}

Reference: Provider Context - Lifecycle Management

5. Audio Issues Caused by Browser Autoplay Policy

Symptom: No sound after initialization, or calling playback methods has no effect

Cause: Browsers prohibit automatic audio playback without user interaction

Solution:

function StartButton() {
const {controller, isReady, isMuted} = useAaaSPilotKit();

const handleStart = useCallback(
() => {
if (controller && isReady) {
// ✅ Operate audio after user gesture trigger
controller.mute(false); // Unmute
controller.input('Hello, I am your digital employee assistant');
}
},
[controller, isReady]
);

return (
<button onClick={handleStart} disabled={!isReady}>
{isMuted ? 'Start Voice Conversation' : 'Start Conversation'}
</button>
);
}

Notes:

  • Audio can only be played after user gesture (click, touch, etc.)
  • Ensure deployment in HTTPS environment
  • Mobile browsers have stricter restrictions

6. AgentService Configuration Conflict

Symptom: Both agentService and agentConfig configured, but Agent connection fails

Cause: Custom agentService will override agentConfig configuration

Solution:

// ❌ Error: Configuring both will cause agentConfig to be ignored
const wrongOptions = {
token: 'your-auth-token-here',
figureId: '209337',
agentConfig: {token: 'xxx', robotId: 'yyy'},
agentService: CustomAgentService // This will override agentConfig
};

// ✅ Solution 1: Use built-in Agent service
const builtinOptions = {
token: 'your-auth-token-here',
figureId: '209337',
ttsPer: 'LITE_audiobook_female_1',
agentConfig: {
token: 'your-token',
robotId: 'your-robot-id'
}
};

// ✅ Solution 2: Use custom Agent service
const customOptions = {
token: 'your-auth-token-here',
figureId: '209337',
ttsPer: 'LITE_audiobook_female_1',
agentService: CustomAgentService // agentConfig not needed
};

Important Reminders:

  • Can only choose one between agentService and agentConfig
  • When using custom agentService, must inherit from BaseAgentService
  • Check if agentService parameter was accidentally passed in

Reference: Introduction - Custom AgentService


Microphone Device Issues

All microphone device-related issues (permissions, HTTPS requirements, device occupancy, etc.) and solutions, please refer to:

👉 Vanilla JS FAQ - Microphone Device Troubleshooting

This chapter includes:

  • How to check if microphone is available
  • Detailed solutions for 6 common errors (error codes 3100-3105)
  • Browser permission setting guides
  • Safari special considerations
  • Complete code examples

All solutions are equally applicable to React version.


More Help

Related Documentation:

Technical Support: