ruvnet/ruflo · error

Invalid outputDim: ${this.config.outputDim}. Must be positiv

Error message

Invalid outputDim: ${this.config.outputDim}. Must be positive.

What it means

BaseGNNLayer.validateConfig() (gnn.ts:485) rejects non-positive outputDim at construction time. outputDim sizes the layer's outgoing node embeddings and its weight matrix, so 0 or negative values cannot produce a valid layer. createLayer() defaults outputDim to 64 when omitted, so this fires only when an explicit invalid value is supplied.

Source

Thrown at v3/@claude-flow/plugins/src/integrations/ruvector/gnn.ts:485

  readonly type: GNNLayerType;
  readonly config: GNNLayerConfig;

  constructor(config: GNNLayerConfig) {
    this.type = config.type;
    this.config = config;
    this.validateConfig();
  }

  /**
   * Validate layer configuration.
   * @throws Error if configuration is invalid
   */
  protected validateConfig(): void {
    if (this.config.inputDim <= 0) {
      throw new Error(`Invalid inputDim: ${this.config.inputDim}. Must be positive.`);
    }
    if (this.config.outputDim <= 0) {
      throw new Error(`Invalid outputDim: ${this.config.outputDim}. Must be positive.`);
    }
    if (this.config.dropout !== undefined && (this.config.dropout < 0 || this.config.dropout > 1)) {
      throw new Error(`Invalid dropout: ${this.config.dropout}. Must be between 0 and 1.`);
    }
    if (this.config.numHeads !== undefined && this.config.numHeads <= 0) {
      throw new Error(`Invalid numHeads: ${this.config.numHeads}. Must be positive.`);
    }
  }

  abstract forward(graph: GraphData): Promise<GNNOutput>;
  abstract messagePass(nodes: NodeFeatures, edges: EdgeFeatures): Promise<NodeFeatures>;

  /**
   * Aggregate messages using the specified method.
   */
  async aggregate(messages: Message[], method: AggregationMethod): Promise<number[]> {
    if (messages.length === 0) {
      return new Array(this.config.outputDim).fill(0);

View on GitHub (pinned to fa13ee4ad6)

Solutions

  1. Pass a positive integer outputDim (or omit it to accept the default 64)
  2. Clamp generated dimension schedules: outputDim = Math.max(1, Math.floor(prev / 2))
  3. Validate loaded configs (JSON checkpoints, sweeps) for dimension fields > 0 before constructing layers

Example fix

// before
const layer = new GCNLayer({ type: 'gcn', inputDim: 128, outputDim: hidden }); // hidden = 0 -> throws

// after
const hidden = Math.max(1, Math.floor(config.hiddenUnits));
const layer = new GCNLayer({ type: 'gcn', inputDim: 128, outputDim: hidden });
Defensive patterns

Strategy: validation

Validate before calling

if (!(Number.isInteger(cfg.outputDim) && cfg.outputDim > 0)) {
  throw new TypeError(`outputDim must be a positive integer, got ${cfg.outputDim}`);
}
const layer = registry.createLayer('gcn', cfg);

Type guard

function isValidDim(v: unknown): v is number {
  return typeof v === 'number' && Number.isInteger(v) && v > 0;
}

Try / catch

try {
  layer = new GCNLayer(config);
} catch (err) {
  if (err instanceof Error && err.message.includes('Invalid outputDim')) {
    config = { ...config, outputDim: 64 }; // safe default
    layer = new GCNLayer(config);
  } else throw err;
}

Prevention

When it happens

Trigger: new GATLayer({ type: 'gat', inputDim: 64, outputDim: -1 }); dimension schedules (e.g. Math.floor(hidden/2)) that evaluate to 0 for small hidden sizes; deserializing a layer config where outputDim is absent and coerced to 0.

Common situations: Auto-generated architectures that halve dimensions each layer until they hit zero; config typos (negative sign); width hyperparameter of 0 from a sweep.

Related errors


AI-assisted analysis of ruvnet/ruflo@fa13ee4ad6 (2026-08-18). Data as JSON: /api/errors/28bdf9a9f94ba40c. Report an issue: GitHub.