7 Errors
dxtr edited this page 2026-10-18 16:18:49 +02:00

Errors

harfbuzz-error

HarfBuzz has no error codes: failing calls return false, NULL or an empty object. cl-harfbuzz checks for those at the call boundary, and for misuse it can see itself, and signals one flat condition class, harfbuzz-error, a subclass of error. It covers three cases:

  1. A HarfBuzz function failed: a file could not be read, a feature string could not be parsed, an allocation failed.
  2. cl-harfbuzz saw that a call could not succeed and stopped it before it reached HarfBuzz: a destroyed object, data that is not a font, a face index or named instance out of range, a buffer read before shaping, an axis the font does not have, bad :start/:end.
  3. The libharfbuzz shared library could not be loaded when cl-harfbuzz was: the message lists each file tried and why it failed, and the hint says what to install.
Reader Value
harfbuzz-error-message what went wrong, in terms of the cl-harfbuzz call (a string)
harfbuzz-error-hint what to do about it (a string), or nil
harfbuzz-error-function the HarfBuzz function that failed, such as "hb_feature_from_string", or nil when cl-harfbuzz caught the problem itself

The report prints the message, then the hint, then the HarfBuzz function if there is one:

(handler-case (hb:shape-text font "x" :features '("bogus feature!"))
  (hb:harfbuzz-error (e)
    (values (hb:harfbuzz-error-function e) (princ-to-string e))))
;; => "hb_feature_from_string"
;;    "\"bogus feature!\" is not a valid feature.
;;     Write features in HarfBuzz's syntax: \"liga\" or \"+liga\" to turn one
;;     on, \"-liga\" to turn it off, \"aalt=2\" for a value, \"smcp[3:5]\" for a range.
;;     (HarfBuzz: hb_feature_from_string failed)"

Errors you are likely to meet

Situation Message Hint Function
libharfbuzz missing, when cl-harfbuzz loads cl-harfbuzz could not load HarfBuzz: Could not load the foreign library LIBHARFBUZZ. (each file tried, and why) Install HarfBuzz 7.0 or newer: on Debian or Ubuntu, libharfbuzz0b. (Windows: restore native\windows-x64\harfbuzz.dll from the repository) —
file missing or unreadable Could not read the font file path: it does not exist or cannot be read. Check the path and the file's permissions. hb_blob_create_from_file_or_fail
data is not a font path / The data is not a font HarfBuzz can read. Pass a TrueType or OpenType font, or a font collection. —
WOFF or WOFF2 data path / The data is a WOFF2 font, which HarfBuzz cannot read. Convert it to TrueType or OpenType first, for example with fontTools. —
face index too large The font has 1 face, so face 3 does not exist. Pass an index below FACE-COUNT of the font. —
destroyed face The face has been destroyed with DESTROY-FACE. Open the font again with MAKE-FACE … Fonts made from it stay usable. —
destroyed font (also font-face of one) The font has been destroyed. Make a new font with MAKE-FONT … A font made with CL-HARFBUZZ/FT2 is destroyed when its cl-ft2 face is closed. —
destroyed buffer The buffer has been destroyed with DESTROY-BUFFER. Make a new buffer with MAKE-BUFFER … —
buffer-glyphs before shape The buffer holds text, not glyphs: it has not been shaped. Shape it with SHAPE first, or shape text in one call with SHAPE-TEXT. —
bad :start / :end END is 9, past the end of the text, which has 3 characters. START and END are character indexes into the text, with 0 <= START <= END <= its length. —
bad feature string "…" is not a valid feature. (feature syntax) hb_feature_from_string
unknown axis The font has no "slnt" axis; its axes are "wght", "wdth". (or: it is not a variable font) Name axes by the tags of FACE-VARIATION-AXES. —
too many coordinates 3 coordinates were given, but the font has 2 axes. Pass at most one coordinate per axis … or set one axis by tag with FONT-AXIS-COORDINATE. —
named instance out of range The font has 3 named instances, so instance 99 does not exist. Pass an index into FACE-NAMED-INSTANCES, or NIL for the font's defaults. —
out of memory HarfBuzz ran out of memory for the buffer. — hb_buffer_create, hb_buffer_add_codepoints or hb_shape

Bad arguments: type-error

The functions declare the types of their arguments and check them when they are called, so an argument of the wrong type, or outside the documented choices, is rejected with a standard type-error by the function it was passed to, before anything reaches HarfBuzz:

  • an object of the wrong kind, such as a face where a font belongs
  • a direction other than :ltr, :rtl, :ttb, :btt, nil
  • an unknown cluster level, buffer flag, font-metric keyword, face-name keyword, or layout :table
  • a tag that is not one to four characters, or for face-table not printable ASCII
  • a script that is not a string of four letters, an ISO 15924 code such as "Latn"
  • a non-string text, language or feature
  • a negative or non-integer index, palette, scale or ppem, or a glyph index, palette, scale or ppem that does not fit in 32 bits; a code point above #x10FFFF; a non-real point size or coordinate
  • a color that is not four octets
(hb:shape-text face "x")
;; type-error: The value #<HB:FACE 6253 glyphs {...}> is not of type CL-HARFBUZZ:FONT
;;             when binding HB:FONT
(hb:shape-text font "x" :direction :up)
;; type-error: The value :UP is not of type (MEMBER NIL :BTT :TTB :RTL :LTR)
;;             when binding :DIRECTION
(setf (hb:buffer-script buffer) "Latin")
;; type-error: The value "Latin" is not of type (OR (STRING 4) NULL)
;;             when binding CL-HARFBUZZ::SCRIPT

Where SBCL can see such a mistake when it compiles the call, as with the constant :up above, it also warns at compile time.

So a harfbuzz-error always means the arguments were well-formed: the font, the state of the object, or HarfBuzz itself refused the call.

Things that are not errors

HarfBuzz is forgiving, and so is cl-harfbuzz where the C API is:

  • A character the font lacks shapes to glyph 0 (.notdef). Check for glyph 0 to trigger font fallback.
  • A feature the font does not have is ignored.
  • Lookups that find nothing return nil: font-char-glyph, font-glyph-name, font-glyph-from-name, font-glyph-extents, font-metric, face-name, face-table, glyph-svg, glyph-png.
  • Out-of-range coordinates are clamped; an out-of-range palette falls back to palette 0.
  • An invalid glyph index gives empty outlines and zero metrics.