babalae/better-genshin-impact · error · ArgumentNullException
实时任务名称不能为空
Error message
实时任务名称不能为空
What it means
ArgumentNullException thrown by Dispatcher.AddTrigger at line 92 when RealtimeTimer.Name is null or empty. RealtimeTimer has a parameterless constructor that leaves Name null (the field is `string?`); only the (string name) and (string name, dynamic config) constructors populate it. TaskTriggerDispatcher.AddTrigger keys on the name, so an empty name cannot route the trigger.
Source
Thrown at BetterGenshinImpact/Core/Script/Dependence/Dispatcher.cs:92
}
/// <summary>
/// 添加实时任务,不会清理之前的任务
/// </summary>
/// <param name="timer"></param>
/// <exception cref="ArgumentNullException"></exception>
/// <exception cref="ArgumentException"></exception>
public void AddTrigger(RealtimeTimer timer)
{
var realtimeTimer = timer;
if (realtimeTimer == null)
{
throw new ArgumentNullException(nameof(realtimeTimer), "实时任务对象不能为空");
}
if (string.IsNullOrEmpty(realtimeTimer.Name))
{
throw new ArgumentNullException(nameof(realtimeTimer.Name), "实时任务名称不能为空");
}
if (!TaskTriggerDispatcher.Instance().AddTrigger(realtimeTimer.Name, realtimeTimer.Config))
{
throw new ArgumentException($"添加实时任务失败: {realtimeTimer.Name}", nameof(realtimeTimer.Name));
}
}
public async Task RunTask(SoloTask soloTask, CancellationTokenSource customCts)
{
// 创建链接的取消令牌源,任何一个取消都会触发
CancellationTokenSource linkedCts = CancellationTokenSource.CreateLinkedTokenSource(
customCts.Token,
CancellationContext.Instance.Cts.Token);
await RunTask(soloTask, linkedCts.Token);
}
View on GitHub (pinned to a7cb36712d)
Solutions
- Always use a name-bearing constructor: `new RealtimeTimer('AutoSkip')`.
- If using the no-arg ctor, set `timer.Name = '...'` before AddTrigger.
- Validate the name string in JS before calling AddTrigger.
Example fix
// before (JS)
const t = new RealtimeTimer();
dispatcher.AddTrigger(t); // throws: Name is null
// after (JS)
const t = new RealtimeTimer('AutoSkip');
dispatcher.AddTrigger(t); Defensive patterns
Strategy: validation
Validate before calling
// JS side
if (!timer.Name) throw new Error('RealtimeTimer.Name is required');
dispatcher.AddTrigger(timer); Type guard
// JS
function hasTimerName(t) { return t != null && typeof t.Name === 'string' && t.Name.length > 0; } Prevention
- Prefer the RealtimeTimer(name) constructor over the no-arg constructor.
- Never pass a freshly `new RealtimeTimer()` without setting Name.
- Validate Name is a non-empty string before AddTrigger.
When it happens
Trigger: JS does `new RealtimeTimer()` (no-arg ctor) then AddTrigger without setting .Name. Or `new RealtimeTimer('')` / `new RealtimeTimer(null)`. The (name, config) constructor was used but name was an empty string literal.
Common situations: Script author used the default constructor and forgot `.Name = '...'`. A variable intended to hold the name was undefined when the constructor ran.
Related errors
AI-assisted analysis of babalae/better-genshin-impact@a7cb36712d (2026-08-13).
Data as JSON: /api/errors/bc970462541cb72d.
Report an issue: GitHub.