Purpose: provide a launching point for explanations and suggestions for resolving warnings and errors generated by the base Tcl interpreter. Similar pages for extensions can be started if this appears useful. The following is an attempt to catalog the various warning messages that a user might find appearing when running Tcl applications. The purpose of this list is not to simply have a list. It is to provide a point where people can add more explanation as to what a particular warning or error means, along with suggestions for solving the situation. In some cases, the solution may be a change in the user's environment. In other cases, the message may indicate an error in the Tcl application. In a few cases, the message may indicate a problem in Tcl itself. Binary: number of elements in list does not match count cannot use "*" in format string with "x" bad field specifier "{buffer}" not enough arguments for all format specifiers missing count for "@" field specifier expected {error1} but got "{error2}" instead Ckalloc: wrong # args: should be "{command} option [args..]" wrong # args: should be "{command} {arg1} file" wrong # args: should be "{command} active file" wrong # args: should be "{command} display file" error accessing {file} wrong # args: should be "{command} onexit file" wrong # args: should be "{command} tag string" bad option "{option}": should be active, break_on_malloc, info, init, onexit tag, trace, trace_on_at_malloc, or validate wrong # args: should be "{command} {arg} count" wrong # args: should be "{command} {arg} on|off" wrong # args: should be "{command} filename" CmdAH: couldn't change working directory to "{dirname}": {posixerror} could not create new link "{path}": that path already exists could not create new link "{path}" using target "{path2}" doesn't exist could not create new link "{path}" pointing to "{path2}": {posixerror} could not read link "{path}": {posixerror} could not readlink "{path}": {posixerror} could not read "{path}": {posixerror} CmdIL: wrong # args: no script following "{clause}" argument wrong # args: no script following "else" argument wrong # args: extra words after "else" clause in "if" command "{command}" isn't a procedure "{command}" isn't a procedure "{command}" isn't a procedure couldn't store default value in variable "{varname}" procedure "{command}" doesn't have an argument "{argname}" bad level "{level}" list doesn't contain element {element} missing starting index "-command" option must be followed by comparison command "-index" option must be followed by list index element {element} missing from sublist "{list}" must be a list -compare command returned non-numeric result CmdMZ: regexp match variables not allowed when using -inline couldn't set variable "{variable}" couldn't set variable "{variable}" extra switch pattern with no body extra switch pattern with no body, this may be due to a comment incorrectly placed outside of a switch body - see the "switch" documentation, or an "; # end switch" comment without the semi-colon. no body specified for pattern "{pattern}" bad operations "{flag}": should be one or more of rwua Encoding: invalid encoding file "{file}" unknown encoding "{encodingname}" LoadAout: bad magic number in intermediate file "{filename}" couldn't open "{fileName}" : {posixerror} File "{fileName}" is not a Tcl load module. Library directory in "{fileName}" ends prematurely. bad magic number in intermediate file "{filename}" error on intermediate file "{filename}": {posixerror} LoadDl: couldn't load file "{filename}": {dlerror} LoadDld: initialization failed for dynamic loader: {dlderror} couldn't load file "{filename}}: {dlderror} initialization failed for dynamic loader: {dlderror} couldn't load file "{filename}": {dlderror} LoadNext: couldn't load file "{fileName}": {memoryerr} LoadOSF: couldn't load file "{fileName}": {memoryerr} LoadShl: couldn't load file "{fileName}": {memoryerr} UnixChan: -handshake RTSCTS not supported for this platform -handshake DTRDSR not supported for this platform -ttycontrol DTR not supported for this platform -ttycontrol RTS not supported for this platform -ttycontrol BREAK not supported for this platform bad value for -handshake: must be one of xonxoff, rtscts, dtrdsr or none bad value for -xchar: should be a list of two elements bad value for -ttycontrol: should be a list of signal,value pairs bad signal for -ttycontrol: must be DTR, RTS or BREAK bad value for -mode: should be baud,parity,data,stop bad value for -mode: parity: should be n, o, e, m, or s bad value for -mode: parity: should be n, o, or 3 bad value for -mode: data: should be 5, 6, 7, or 8 bad value for -mode: stop: should be 1 or 2 couldn't open "{filename}": {posixerror} can't get peername: {posixerror} can't get sockname: {posixerror} couldn't open socket: {posixerror} couldn't open socket: {posixerror} "{channel}" wasn't opened for writing "{channel}" wasn't opened for reading cannot get a FILE * for "{channel}" "{channel}" cannot be used to get a FILE * UnixFCmd: could not read "{filename}": {posixerror} could not read "{filename}": {posixerror} could not read "{filename}": {posixerror} could not set group for file "{filename}": group "{groupname}" does not exist could not set group for file "{filename}": {posixerror} could not set owner for file "{filename}": user "{username}" does not exist could not set owner for file "{filename}": {posixerror} could not read "{filename}": {posixerror} UnixFile: couldn't read directory "{dirname}": {posixerror} error getting working directory name: {posixerror} UnixPipe: couldn't create pipe: {posixerror} couldn't fork child process: {posixerror} {errno}{posixerror} UnixTest: wrong # arguments: should be "{progname} option ... " bad index {pipenum} wrong # arguments: should be "{progname} clear index" wrong # arguments: should be "{progname} counts index" wrong # arguments: should be "{progname} create index readMode writeMode" couldn't open pipe: {posixerror} bad read mode "{readmode}" bad read mode "{readmode}" wrong # arguments: should be "{progname} empty index" wrong # arguments: should be "{progname} fill index" ?? wrong # arguments: should be "{progname} fillpartial index" ?? wrong # arguments: should be "{progname} wait index readable/writable timeout" pipe {pipename} doesn't exist readable writable bad option "{optionname}": must be close, clear, counts, create, empty, fill, fillpartial, oneevent, wait, or windowevent wrong # arguments: should be "{progname} file readable|writable|both timeout" bad argument "{argument}": must be readable, writable, or both readable writable wrong # arguments: should be "{command} argv0" wrong # args: should be "{command} channelName forWriting" Tcl_GetOpenFile succeeded but FILE * NULL! wrong # args: should be "{command} defaultDir" wrong # args: should be "{command} {DefaultEncodingDir} sigaction: {posixerror" alarm: {posixerror" warning: sigaction SA_RESTART not support on this platformo "0" "1" XtTest: wrong # arguments: should be "{command} option ... " bad option "{option}": must be done or wait ---- [DKF]: '''WARNING!''' The [TCT] and Core Maintainers make no general commitment to preserve any particular error messages. A higher level of commitment is made to preserving the [errorCode] contents (but only where they are not ''NONE'') and code should match against that if possible. Use this page just to help when manually tracking down problems from unexpected error messages. Also note that most of Tcl's built in commands generate their ''wrong # args: ...'' messages by calling a helper function, [Tcl_WrongNumArgs], which handles the whole bunch of subtleties involved. ---- [Schnexel]: ''couldn't set loop variable'' ??? [glennj]: This happens if you use an array variable as a loop variable: array set varname {} foreach varname {1 2 3} break Current Tcl error message is clear: `can't set "varname": variable is array` Older Tcl message is more obscure: `couldn't set loop variable: "varname"` ---- [Fabricio Rocha] - 04-Feb-2010 - After more than 3 years, had there been any advances in Tcl's error handling? I am studying ways to implement error/exception handling in Tcl/Tk apps and, according to what I've read, relying on the error strings given by `::errorInfo` is prone to problems, as [DKF] said; but `::errorCode` contents are too limited for a clear detection of what happened, and even some core commands don't use appropriate error codes. By the way, some questions arise. Is there any way to translate the default error messages? I can only think that the solution is to override them all with translatable strings. [Lars H]: Is the problem you perceive that [errorCode] cannot encode enough information, or just that most commands throwing errors don't bother supplying any information for it? I believe the latter case is generally (among the powers that be) considered as old bad habits, which the new [try] command should act as an incentive for breaking. [DKF]: I've been working on improving things, but it's a gigantic and complex job. I welcome review by more sets of eyes. (Longer term, consider the error code space starting with the word `TK` to also be reserved, for obvious reasons...) [Fabricio Rocha] - 05-Feb-2010 - Actually, from what I've read so far, ::errorCode, [catch] and [return] provide a very good infrastructure for error handling, and CAN provide enough information about errors, but they seem to be "underused" and, if they are not, there's a hole in the documentation. I can't assure by myself that even some core commands make bad or little use of this infrastructure (this is what I read in a comp.lang.tcl post mentioned in one page of this wiki), but as said [errorCode%|%here%|%], "''the standard ARITH, CHILD*, NONE, and POSIX only cover a fraction of all possible error conditions''". If the error handling mechanisms are little used by the core itself, it's no wonder that third-party code uses it even less -- actually, tutorials and sample snippets very rarely tell to newbies like me that such infrastructure exists and should be used more often. So far, I have been using [return] just for returning values, as we usually do in C, and this have often left me scratching my head thinking how could I tell a caller [proc] that the returned value is actually an error code, while this feature is simply and beautifully built-in. Maybe what I imagine for error handling could fit well in a [tcllib] package -- for example, a set of internationalized (or ''internationalizable'') error messages, the possibility to have these messages shown in a Tk dialog rather than the console, facilities for treating specific errors properly while avoiding the interpreter or the whole script to collapse, and so on. I still haven't found out, for example, if there is a way to intercept and treat syntax and parsing errors in Tcl itself (by the way, where did the above list come from? From Tcl C sources?) [DKF]: I'm working in 8.6 to expand the set of error messages. There are two particular categories of interest: * '''TCL WRONGARGS''' – used to indicate that the wrong number of arguments was passed (see human-readable message for details). * '''TCL LOOKUP''' ''type value'' – used to indicate that a search for a ''type'' with name ''value'' failed. There are others that need documenting too. The actual error messages (as opposed to the `errorCode`s) are not documented precisely because they may change and are intended for human consumption. [Fabricio Rocha] - These are indeed quite interesting categories. In fact, I think that the human-readable error messages are in a certain way self-documented. I presume that this have been discussed for years, but would it be possible that these human messages could be kept and generated in a "core package" in Tcl itself, updated (if needed) in each release, to which one could set a [msgcat] file with translated strings? [DKF]: We're not going to run error messages through [msgcat] ourselves (for one thing, what about errors generated inside [msgcat]?) and we happen to think that code should normally not display any internal error messages from Tcl to users anyway as they are usually indicative of program bugs and not things that users can do anything about, but there's no reason at all for applications to avoid such a strategy as you suggest. [RZ] Sometimes error messages are usefull p.e. "integer value too large to represent". But how should a developer detect these? Also the [msgcat] package work only on the script level. What about adding access to these functionality from the C-side. ====== /* Function to translate given string */ const char *Tcl_msgcat(Tcl_Interp *interp, const char *ns, const char *string) { Tcl_Obj *msgcatObjv[3]; if (interp == NULL || ns == NULL || format == NULL) return format; msgcatObjv[0] = Tcl_NewStringObj("::msgcat::mcns",-1); msgcatObjv[1] = Tcl_NewStringObj(ns,-1); msgcatObjv[2] = Tcl_NewStringObj(string,-1); if (Tcl_EvalObjv(interp, 3, msgcatObjv, TCL_EVAL_GLOBAL) != TCL_OK) { return (format); } return (Tcl_GetStringResult(msgcatInterp)); } ====== The used ::msgcat::mcns should be: ====== proc ::msgcat::mcns {ns src} { variable Msgs variable Loclist foreach loc $Loclist { if {[dict exists $Msgs $loc $ns $src]} { return [dict get $Msgs $loc $ns $src] } } return $src } ====== Optimizations are possible (default interpreter, static msgcatObjv, translate ::msgcat::mcns in C-code). The last one allows to take care of possible errors inside [msgcat]. So with a default interpreter this could be in the core enabled/disabled like: ====== #ifdef TCL_USE_MSGCAT #define tclMsgcat(string) Tcl_msgcat(msgcatInterp,"tcl",string) #else #define tclMsgcat(string) string #endif ====== Each used string would be inside a 'tclMsgcat(..) call and could be automatically parsed and inserted in a translation file. Extension writers could also use this function with their own namespace. <> Documentation | Internals | Tcl Library