File has unexpected syntax error when building documentation

Zig Version: 0.13.0
I am working in WSL (Ubuntu 22.04.4 LTS) on a windows 11 machine.

I want to use the zig build system to generate documentation for my project. I followed the zig.guide page. Only the documentation for root.zig populates on the webpage that is created from zig build docs.

Whenever I try to import another file in root.zig and expose it with pub, the following error shows up when I open the webpage console:

error: can't index 'lib/WhateverFile.zig' because it has syntax errors

I have created a small reproducible example of my issue.

Directory is structured like:

src/
    rank.zig
    root.zig
build.zig
build.zig.zon

Here are the files:

rank.zig

//! Implementation of playing card ranks

/// This is a rank
pub const Rank = enum {
    Nine,
};

root.zig

//! This module provides functions for dealing with spreadsheets.

const std = @import("std");

pub const Rank = @import("rank.zig").Rank;

/// A spreadsheet position
pub const Pos = struct {
    /// (0-indexed) row
    x: u32,
    /// (0-indexed) column
    y: u32,

    /// The top-left position
    pub const zero: Pos = .{ .x = 0, .y = 0 };

    /// Illegal position
    pub const invalid_pos: Pos = .{
        .x = std.math.maxInt(u32),
        .y = std.math.maxInt(u32),
    };
};

build.zig

const std = @import("std");

pub fn build(b: *std.Build) void {
    const target = b.standardTargetOptions(.{});
    const optimize = b.standardOptimizeOption(.{});

    const lib = b.addStaticLibrary(.{
        .name = "lib",
        .root_source_file = b.path("src/root.zig"),
        .target = target,
        .optimize = optimize,
    });
    b.installArtifact(lib);

    const install_docs = b.addInstallDirectory(.{
        .source_dir = lib.getEmittedDocs(),
        .install_dir = .prefix,
        .install_subdir = "docs",
    });

    const docs_step = b.step("docs", "Install docs into zig-out/docs");
    docs_step.dependOn(&install_docs.step);
}

build.zig.zon

.{
    .name = "test_zig_docs",
    .version = "0.0.0",
    .dependencies = .{},
    .paths = .{
        "build.zig",
        "build.zig.zon",
        "src",
    },
}

Below is a screenshot of the error that appears when spinning up the webpage using python -m http.server 8000 -d docs/ as suggested by zig.guide.

Does anyone know what I am doing wrong? The rank.zig file doesn’t have any syntax errors as I understand it.

Hi @hello, welcome to Ziggit! I don’t see any issue with your rank.zig file as written either, but I’d like to help potentially make the issue easier to debug.

The Autodoc (Zig documentation) Wasm implementation code is compiled on demand from within the lib directory shipped with your Zig installation. That means that you can make changes to Autodoc and have them reflect immediately the next time you build your documentation, by editing the files under lib/docs/wasm in your Zig installation directory.

Within that directory, find the file Walk.zig, then in that file search for “can’t index”, and edit the surrounding if (ast.errors.len > 0) block as follows:

if (ast.errors.len > 0) {
    log.err("can't index '{s}' because it has syntax errors", .{file_index.path()});

    const token_offsets = ast.tokens.items(.start);
    var rendered_err: std.ArrayListUnmanaged(u8) = .{};
    defer rendered_err.deinit(gpa);
    for (ast.errors) |err| {
        const err_offset = token_offsets[err.token] + ast.errorOffset(err);
        const err_loc = std.zig.findLineColumn(ast.source, err_offset);
        rendered_err.clearRetainingCapacity();
        try ast.renderError(err, rendered_err.writer(gpa));
        log.err("{s}:{}:{}: {s}", .{ file_index.path(), err_loc.line + 1, err_loc.column + 1, rendered_err.items });
    }
    return file_index;
}

Then, save that file and run zig build docs again. The effect of that change will be that when you open the console of the docs page again, it will tell you the specific syntax error(s) which were found and where (line and column). That might help point you in the right direction, at least by providing some more context rather than just “syntax errors exist”.

1 Like

Thank you for the response! I made those changes and here is what it output:

error: can't index lib/rank.zig because it has syntax errors
error: lib/rank.zig:6:2: expected ';' after declaration

But rank.zig has a ; on line 6 after the ending brace. There must be something simple I am missing.

Hmm, there are two possibilities I can think of:

  1. The file might not have been saved correctly; if you open the file in another text editor or cat it in a terminal, does it have the content you expect?
  2. The file doesn’t end in a newline, which is assumed by Autodoc (and which you can guarantee by running zig fmt on the file): zig/lib/docs/wasm/Walk.zig at 1a1389c513119c344d2eafefd3b6353b2c6cd343 · ziglang/zig · GitHub

the second was the case. rank.zig did not have a newline at the end.

Thank you very much for your help. I added the newline and used cat to ensure it is there. From here the docs then work fine as you hypothesized.

However, I am still experiencing some pretty user-unfriendly behavior. Whenever I make changes to rank.zig and try to rebuild the docs, nothing happens until I delete ./.zig-cache/ or my HOME level cache at ~/.cache/zig.

This is pretty annoying, is there a --force option or an equivalent?

Separately, shouldn’t it be a concern that the assertion (assert(source[source.len - 1] == '\n')) in parse in Walk.zig did not bubble up that it failed, instead continuing through with undefined behavior (removing the semicolon after the Rank declaration)? Am I supposed to be running zig build docs with another flag of some sort?

1 Like

I agree that the error handling and reporting of this case isn’t great. Once I get a bit more time I’m hoping to make a PR aimed at improving this error handling:

  1. Errors should be displayed on the page (e.g. in a red box at the bottom) as opposed to only in the console.
  2. Syntax errors should be reported more precisely as in the patch I shared earlier in this thread.
  3. The “file ends in newline” check should not be an assert, it should be a check that results in an error being logged similarly to if it were a syntax error.

As for the cache issue, it looks like (based on some brief experimentation) changes to root.zig do properly invalidate the cache and cause the docs to be updated, but changes to rank.zig do not (as you noticed). Unfortunately I don’t know much of anything about the internals of Zig’s caching system, so I don’t know why this is. I think it’s worth a report on the issue tracker, though. (Related, but not identical issue: build system caching ignores changes to new autodoc wasm source files · Issue #19261 · ziglang/zig · GitHub)

1 Like